1, 解析主机
2. 向 cmbServerNode 中添加所有节点(电脑)
3. 选择一个OPC服务器, 连接它, 并将它名下的OPC 节点写入 ListItems
4. 使用委托解析OPC中的信息(异步读取), 提取出Value和Time, 存入OPClist中, OPClist 事先建好了一个类, 里面有Tag, value, Time, 并为dvg准备数据源
5. 设置同步修改 异步修改操作器
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Threading; using OPCAutomation; namespace OPCClientDemon { public partial class FrmOPCClient : Form { public FrmOPCClient() { InitializeComponent(); this.Load += FrmOPCClient_Load; } private void FrmOPCClient_Load(object sender, EventArgs e) { this.btnRefreshList_Click(null, null); this.timer1.Interval = 1000; //时间从1秒开始 this.timer1.Enabled = true; this.dtgData.AutoGenerateColumns = false; //自动生成列 Control.CheckForIllegalCrossThreadCalls = false; } //定义OPC服务器; OPCServer kepServer; //定义OPC服务器Groups; OPCGroups kepGroups; OPCGroup kepGroup; OPCItems kepItems; OPCBrowser kepBrowser; //定义OPC变量集合 List<OPCItem> opcList = new List<OPCItem>(); List<int> serverHandles = new List<int>(); List<int> clientHandles = new List<int>(); List<string> tempIDList = new List<string>(); //定义返回的OPC标签错误码 Array iErrors; //定义要添加的OPC标签的标识符 Array strTempIDs; Array strClientHandles; Array strServerHandles; Array readServerHandles; Array writeServerHandles; Array writeArrayHandles; Array readError; Array writeError; int readTransID; int writeTransID; int readCancelID; int writeCancelID; private void btnRefreshList_Click(object sender, EventArgs e) { this.cmbServerNode.Items.Clear(); //GetHostEntry是DNS类里面的一个方法,可以将主机名(域名)和IP地址相互解析的一个类 IPHostEntry IPhost = Dns.GetHostEntry(Environment.MachineName); //获取主机名称 DESKTOP-IH9OA15 并解析地址 if (IPhost.AddressList.Length > 0) { int count = IPhost.AddressList.Length; for (int i = 0; i < count; i++) { //解析主机名称 string HostName = Dns.GetHostEntry(IPhost.AddressList[i].ToString()).HostName; //绑定下拉菜单 if (!this.cmbServerName.Items.Contains(HostName))//读取所有主机名称,记录其节点 { this.cmbServerNode.Items.Add(HostName); } } } else { return; } //Thread th = new Thread(LL); //th.IsBackground = true; //th.Start(IPhost); } //void LL(object o) //{ // IPHostEntry IPhost = o as IPHostEntry; // if (IPhost.AddressList.Length > 0) // { // int count = IPhost.AddressList.Length; // for (int i = 0; i < count; i++) // { // //解析主机名称 // string HostName = Dns.GetHostEntry(IPhost.AddressList[i].ToString()).HostName; // //绑定下拉菜单 // if (!this.cmbServerName.Items.Contains(HostName))//读取所有主机名称,记录其节点 // { // this.cmbServerNode.Items.Add(HostName); // } // } // } // else // { // return; // } //} private void cmbServerNode_SelectedIndexChanged(object sender, EventArgs e) { //清空菜单 this.cmbServerName.Items.Clear(); //通过OPCAutomation 建立OPCserver kepServer = new OPCServer(); object serverList = kepServer.GetOPCServers(this.cmbServerNode.Text.Trim());//通过主机IP获得所有OPC服务器 Thread th1 = new Thread(ThreadCmbName); th1.IsBackground = true; th1.Start(serverList); } void ThreadCmbName(object o) { Array arr1 = o as Array; foreach (string item in arr1) { if (!this.cmbServerName.Items.Contains(item)) { this.cmbServerName.Items.Add(item); } } } private void btnConnect_Click(object sender, EventArgs e) { //连接选择的OPC服务器 if (this.btnConnect.Text=="Connect") { try { kepServer.Connect(this.cmbServerName.Text.Trim(), this.cmbServerNode.Text.Trim()); } catch (Exception err1) { MessageBox.Show(err1.Message, "连接失败"); //throw err1; } this.btnConnect.Text = "Disconnect"; //对kepGroups对象赋值 kepGroups = kepServer.OPCGroups; //对kepGroups属性设置 kepGroups.DefaultGroupDeadband = 0;//Group的默认死区,变化量超过死区后将会触发DataChange事件 kepGroups.DefaultGroupIsActive = true; //以后添加的Group是否默认激活 kepGroup = kepGroups.Add("Group1"); kepGroup.IsActive = true; kepGroup.IsSubscribed = true; //订阅模式 kepGroup.UpdateRate = 250; //刷新率 kepGroup.AsyncReadComplete += KepGroup_AsyncReadComplete; //建立委托 异步读取完成 kepBrowser = kepServer.CreateBrowser(); kepBrowser.ShowBranches(); //OPCBrowser遍历构建树枝 kepBrowser.ShowLeafs(true); //叶节点. foreach (object item in kepBrowser) { this.ListItems.Items.Add(item.ToString()); } } else { if (kepServer != null) { kepServer.Disconnect(); kepServer = null; this.btnConnect.Text = "Connect"; } } } //使用委托解析 void KepGroup_AsyncReadComplete( int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps, ref Array Errors) { for (int i = 1; i <=NumItems; i++) { object Value = ItemValues.GetValue(i); if (Value != null) { this.opcList[i - 1].Value = Value.ToString();//注意减1 //this.opcList[i-1].Time = ((DateTime)TimeStamps.GetValue(i)).AddHours(8).ToLongTimeString(); this.opcList[i - 1].Time = Convert.ToDateTime(((DateTime)TimeStamps.GetValue(i)).AddHours(8)); } } this.dtgData.DataSource = null; this.dtgData.DataSource = this.opcList; //为dvg指定数据源 //throw new NotImplementedException(); 解析 } private void ListItems_DoubleClick(object sender, EventArgs e) { if (this.ListItems.SelectedItem != null) { opcList.Add(new OPCItem() { Tag = this.ListItems.SelectedItem.ToString() }); } tempIDList.Clear(); clientHandles.Clear(); tempIDList.Add("0"); clientHandles.Add(0); int count = this.opcList.Count; for (int i = 0; i < count; i++) { tempIDList.Add(this.opcList[i].Tag); clientHandles.Add(i + 1); } strTempIDs = (Array)tempIDList.ToArray(); strClientHandles = (Array)clientHandles.ToArray(); kepItems = kepGroup.OPCItems; //KepItems添加标签 kepItems.AddItems(this.opcList.Count, ref strTempIDs, ref strClientHandles, out strServerHandles, out iErrors); serverHandles.Clear(); serverHandles.Add(0); for (int i = 0; i < count; i++) { serverHandles.Add(Convert.ToInt32(strServerHandles.GetValue(i + 1))); } readServerHandles = (Array)serverHandles.ToArray(); } private void timer1_Tick(object sender, EventArgs e) { this.lbl_CurrentTime.Text = "当前时间:" + DateTime.Now.ToLongTimeString(); if (kepServer!= null) { if (kepServer.ServerState == 1) { this.lbl_Status.Text = "Connected"; } else { this.lbl_Status.Text = "Disonnected"; } } if (this.opcList.Count>0) { if (kepServer!=null) { kepGroup.AsyncRead(this.opcList.Count, ref readServerHandles, out readError, readTransID, out readCancelID); } } } private void dtgData_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { if (this.dtgData.SelectedRows !=null) { int index = this.dtgData.CurrentRow.Index; OPCItem objItem = this.opcList[index]; Frm_Modify objFrm = new Frm_Modify(objItem.Value);//跨屏操作 DialogResult res = objFrm.ShowDialog(); int[] serverHandle = new int[] { 0,Convert.ToInt32(strServerHandles.GetValue(index+1))}; object[] values = new object[2]; string[] modifyResult; writeServerHandles = (Array)serverHandle; if (res==DialogResult.OK) { modifyResult = objFrm.Tag.ToString().Split('|');//使用哪个屏幕的Tag values[1] = modifyResult[0]; writeArrayHandles = (Array)values; if (modifyResult[1]=="1") { kepGroup.AsyncWrite( 1, writeServerHandles,writeArrayHandles, out writeError, writeTransID, out writeCancelID);//异步 } else //同步 { kepGroup.SyncWrite(1, ref writeServerHandles, ref writeArrayHandles, out writeError); } } } } private void dtgData_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { new DataGridViewStyle().DgvRowPostPaint(this.dtgData, e); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace OPCClientDemon { public partial class Frm_Modify : Form { public Frm_Modify(string Value) { InitializeComponent(); this.txtInitial.Text = Value; } private void btn_OK_Click(object sender, EventArgs e) { string Res = string.Empty; if (this.chk_Async.Checked) { Res = this.txtModify.Text.Trim() + "|" + "1"; } else { Res = this.txtModify.Text.Trim() + "|" + "0"; } this.Tag = Res; this.DialogResult = DialogResult.OK; this.Close(); } private void btn_Cancel_Click(object sender, EventArgs e) { this.Close(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OPCClientDemon { public class OPCItem { //OPCItem变量名 public string Tag { get; set; } //OPCItem值 public string Value { get; set; } public DateTime Time { get; set; } } }