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; }
}
}