C# OPC客户端代码

C#开发的OPC客户端代码,比较简单可以实现搜索本地主机,IP以及本地OPC服务器功能,可以添加标签,实现数据的获取及修改。

001 using System;
002 using System.Collections.Generic;
003 using System.ComponentModel;
004 using System.Data;
005 using System.Drawing;
006 using System.Linq;
007 using System.Text;
008 using System.Windows.Forms;
009 using System.Net;
010 using OPCAutomation;
011 using System.Net.Sockets;
012 using System.Collections.Specialized;
013
014 namespace OMTGate
015 {
016     public partial class MainForm : Form
017     {
018         public MainForm()
019         {
020             InitializeComponent();
021         }
022
023
024         #region 私有变量
025         /// <summary>
026         /// OPCServer Object
027         /// </summary>
028         OPCServer KepServer;
029         /// <summary>
030         /// OPCGroups Object
031         /// </summary>
032         OPCGroups KepGroups;
033         /// <summary>
034         /// OPCGroup Object
035         /// </summary>
036         OPCGroup KepGroup;
037         /// <summary>
038         /// OPCItems Object
039         /// </summary>
040         OPCItems KepItems;
041         /// <summary>
042         /// OPCItem Object
043         /// </summary>
044         OPCItem KepItem;
045         /// <summary>
046         /// 主机IP
047         /// </summary>
048         string strHostIP = "";
049         /// <summary>
050         /// 主机名称
051         /// </summary>
052         string strHostName = "";
053         /// <summary>
054         /// 连接状态
055         /// </summary>
056         bool opc_connected = false;
057         /// <summary>
058         /// 客户端句柄
059         /// </summary>
060         int itmHandleClient = 0;
061         /// <summary>
062         /// 服务端句柄
063         /// </summary>
064         int itmHandleServer = 0;
065
066         DataTable dt = new DataTable();
067                  
068         #endregion
069
070         private void btnNumeServer_Click(object sender, EventArgs e)
071         {
072             //获取计算机名
073             strHostName = Dns.GetHostName();
074             txtComputerName.Text = strHostName;
075
076             //获取IP地址
077             IPAddress[] localIPs;
078             localIPs = Dns.GetHostAddresses(strHostName);
079             StringCollection IpCollection = new StringCollection();
080             foreach (IPAddress ip in localIPs)
081             {
082                 //根据AddressFamily判断是否为ipv4,如果是InterNetWorkV6则为ipv6
083                 if (ip.AddressFamily == AddressFamily.InterNetwork)
084                     IpCollection.Add(ip.ToString());
085             }
086             string[] IpArray = new string[IpCollection.Count];
087             IpCollection.CopyTo(IpArray, 0);
088             foreach (string ip in IpArray)
089             {
090                 cmbIPAddress.Items.Add(ip);
091             }
092             cmbIPAddress.SelectedIndex = 0;
093
094             //获取本地计算机上的OPCServerName
095             try
096             {
097                 KepServer = new OPCServer();
098                 object serverList = KepServer.GetOPCServers(strHostName);
099
100                 foreach (string turn in (Array)serverList)
101                 {
102                     cmbServerName.Items.Add(turn);
103                 }
104                 cmbServerName.SelectedIndex = 0;
105                 btnConnectServer.Enabled = true;
106             }
107             catch (Exception err)
108             {
109                 MessageBox.Show("枚举本地OPC服务器出错:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
110             }
111         }
112
113         private void btnConnectServer_Click(object sender, EventArgs e)
114         {
115             try
116             {
117                 if (!ConnectRemoteServer(cmbIPAddress.Text, cmbServerName.Text))
118                 {
119                     return;
120                 }
121
122                 btnSet.Enabled = true;
123
124                 opc_connected = true;
125
126                 GetServerInfo();
127
128                 RecurBrowse(KepServer.CreateBrowser());
129
130                 if (!CreateGroup())
131                 {
132                     return;
133                 }
134             }
135             catch (Exception err)
136             {
137                 MessageBox.Show("初始化出错:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
138             }
139         }
140
141         private void btnSet_Click(object sender, EventArgs e)
142         {
143             SetGroupProperty();
144         }
145
146         List<string> itemList = new List<string>();
147         int count = 0;
148         private void btnAddItem_Click(object sender, EventArgs e)
149         {
150             try
151             {
152                 //if (itmHandleClient != 0)
153                 //{
154                 //    this.txtTagValue.Text = "";
155                 //    this.txtQualities.Text = "";
156                 //    this.txtTimeStamps.Text = "";
157
158                 //    Array Errors;
159                 //    OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);
160                 //    //注:OPC中以1为数组的基数
161                 //    int[] temp = new int[2] { 0, bItem.ServerHandle };
162                 //    Array serverHandle = (Array)temp;
163                 //    //移除上一次选择的项
164                 //    KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);
165                 //}
166                 itmHandleClient = count;
167                 KepItem = KepItems.AddItem(lsbTagList.SelectedItem.ToString(), itmHandleClient);
168                 //itemList.Add(lsbTagList.SelectedItem.ToString());
169                 itmHandleServer = KepItem.ServerHandle;
170                 count++;
171                 textBox1.Text = KepItems.Count.ToString();
172                 DataRow dr = dt.NewRow();
173                 dr["标签"] = lsbTagList.SelectedItem.ToString();
174                 dr["测量值"] = "";
175                 dr["质量"] = "";
176                 dr["时间戳"] = "";
177                 dt.Rows.Add(dr);
178             }
179             catch (Exception err)
180             {
181                 //没有任何权限的项,都是OPC服务器保留的系统项,此处可不做处理。
182                 //itmHandleClient = 0;
183                 //txtTagValue.Text = "Error ox";
184                 //txtQualities.Text = "Error ox";
185                 //txtTimeStamps.Text = "Error ox";
186                 MessageBox.Show("此项为系统保留项:" + err.Message, "提示信息");
187             }
188         }
189
190         /// <summary>
191         /// 设置组属性
192         /// </summary>
193         private void SetGroupProperty()
194         {
195             KepServer.OPCGroups.DefaultGroupIsActive = Convert.ToBoolean(txtGroupIsActive.Text);
196             KepServer.OPCGroups.DefaultGroupDeadband = Convert.ToInt32(txtGroupDeadband.Text);
197             KepGroup.UpdateRate = Convert.ToInt32(txtUpdateRate.Text);
198             KepGroup.IsActive = Convert.ToBoolean(txtIsActive.Text);
199             KepGroup.IsSubscribed = Convert.ToBoolean(txtIsSubscribed.Text);
200         }
201
202         /// <summary>
203         /// 连接OPC服务器
204         /// </summary>
205         /// <param name="remoteServerIP">OPCServerIP</param>
206         /// <param name="remoteServerName">OPCServer名称</param>
207         private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
208         {
209             try
210             {
211                 KepServer.Connect(remoteServerName, remoteServerIP);
212
213                 if (KepServer.ServerState == (int)OPCServerState.OPCRunning)
214                 {
215                     tsslServerState.Text = "已连接到-" + KepServer.ServerName + "   ";
216                 }
217                 else
218                 {
219                     //这里你可以根据返回的状态来自定义显示信息,请查看自动化接口API文档
220                     tsslServerState.Text = "状态:" + KepServer.ServerState.ToString() + "   ";
221                 }
222             }
223             catch (Exception err)
224             {
225                 MessageBox.Show("连接远程服务器出现错误:" + err.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
226                 return false;
227             }
228             return true;
229         }
230
231         /// <summary>
232         /// 获取服务器信息,并显示在窗体状态栏上
233         /// </summary>
234         private void GetServerInfo()
235         {
236             tsslServerStartTime.Text = "开始时间:" + KepServer.StartTime.ToString() + "    ";
237             tsslversion.Text = "版本:" + KepServer.MajorVersion.ToString() + "." + KepServer.MinorVersion.ToString() + "." + KepServer.BuildNumber.ToString();
238         }
239
240         /// <summary>
241         /// 列出OPC服务器中所有节点
242         /// </summary>
243         /// <param name="oPCBrowser"></param>
244         private void RecurBrowse(OPCBrowser oPCBrowser)
245         {
246             //展开分支
247             oPCBrowser.ShowBranches();
248             //展开叶子
249             oPCBrowser.ShowLeafs(true);
250             foreach (object turn in oPCBrowser)
251             {
252                 lsbTagList.Items.Add(turn.ToString());
253             }
254         }
255
256         /// <summary>
257         /// 创建组
258         /// </summary>
259         private bool CreateGroup()
260         {
261             try
262             {
263                 KepGroups = KepServer.OPCGroups;
264                 KepGroup = KepGroups.Add("OPCDOTNETGROUP");
265                 SetGroupProperty();
266                 KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
267                 KepGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);
268                 KepItems = KepGroup.OPCItems;
269             }
270             catch (Exception err)
271             {
272                 MessageBox.Show("创建组出现错误:" + err.Message, "创建组出错", MessageBoxButtons.OK, MessageBoxIcon.Warning);
273                 return false;
274             }
275             return true;
276         }
277
278         /// <summary>
279         /// 每当项数据有变化时执行的事件
280         /// </summary>
281         /// <param name="TransactionID">处理ID</param>
282         /// <param name="NumItems">项个数</param>
283         /// <param name="ClientHandles">项客户端句柄</param>
284         /// <param name="ItemValues">TAG值</param>
285         /// <param name="Qualities">品质</param>
286         /// <param name="TimeStamps">时间戳</param>
287         void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
288         {
289             //DataTable dt = new DataTable();
290             //dt.Columns.Add("标签", System.Type.GetType("System.String"));
291             //dt.Columns.Add("测量值", System.Type.GetType("System.String"));
292             //dt.Columns.Add("质量", System.Type.GetType("System.String"));
293             //dt.Columns.Add("时间戳", System.Type.GetType("System.String"));
294              
295             //为了测试,所以加了控制台的输出,来查看事物ID号
296             //Console.WriteLine("********"+TransactionID.ToString()+"*********");
297             for (int i = 1; i <= NumItems; i++)
298             {
299                 //DataRow dr = dt.NewRow();
300                 //dr["标签"] = itemList[i-1];
301                 //dt.Columns["测量值"][i] = ItemValues.GetValue(i).ToString();
302                 //dt.Columns["质量"][i] = Qualities.GetValue(i).ToString();
303                 //dt.Columns["时间戳"][i] = TimeStamps.GetValue(i).ToString();
304                 textBox2.Text = ClientHandles.GetValue(i).ToString();
305                 dt.Rows[Convert.ToInt32(ClientHandles.GetValue(i).ToString().Trim())][1] = ItemValues.GetValue(i).ToString();
306                 dt.Rows[Convert.ToInt32(ClientHandles.GetValue(i).ToString().Trim())][2] = Qualities.GetValue(i).ToString();
307                 dt.Rows[Convert.ToInt32(ClientHandles.GetValue(i).ToString().Trim())][3] = TimeStamps.GetValue(i).ToString();
308                 //dt.Rows.Add(dr);
309             }
310             //dgvResultList.DataSource = dt;
311         }
312
313         /// <summary>
314         /// 写入TAG值时执行的事件
315         /// </summary>
316         /// <param name="TransactionID"></param>
317         /// <param name="NumItems"></param>
318         /// <param name="ClientHandles"></param>
319         /// <param name="Errors"></param>
320         void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
321         {
322             lblState.Text = "";
323             for (int i = 1; i <= NumItems; i++)
324             {
325                 lblState.Text += "Tran:" + TransactionID.ToString() + "   CH:" + ClientHandles.GetValue(i).ToString() + "   Error:" + Errors.GetValue(i).ToString();
326             }
327         }
328
329         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
330         {
331             if (!opc_connected)
332             {
333                 return;
334             }
335
336             if (KepGroup != null)
337             {
338                 KepGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
339             }
340
341             if (KepServer != null)
342             {
343                 KepServer.Disconnect();
344                 KepServer = null;
345             }
346
347             opc_connected = false;
348         }
349
350         private void MainForm_Load(object sender, EventArgs e)
351         {
352             dt.Columns.Add("标签", System.Type.GetType("System.String"));
353             dt.Columns.Add("测量值", System.Type.GetType("System.String"));
354             dt.Columns.Add("质量", System.Type.GetType("System.String"));
355             dt.Columns.Add("时间戳", System.Type.GetType("System.String"));
356
357             dgvResultList.DataSource = dt;
358         }
359     }
360 }
http://bbs.51cto.com/thread-1065491-1-1.html


标签和数据的显示是设计了一个表格,可以动态添加标签,显示标签名称、实时值、质量及时间戳。用于实际项目尚需修改!

猜你喜欢

转载自blog.csdn.net/biyusr/article/details/52921148