,1,通过主机名解析IP,将IP下的opc服务器读出来,建立new opc server,并连接(opc服务器名,主机名)
2,设置opc服务器下的groups参数(死区,激活)。
3,groups下面add一个新的group,设置激活,刷新率,订阅(异步)
4,使用异步读取完成的委托,通过tag读出value,送入泛型opclist属性。
5,使用kepserver.OPCItems下的AddItems,通过opclist的count,名称,添加Items。并通过out 返回strServerHandles 服务器句柄。
6,对 strServerHandles 进行处理,getvalue,toint32,变成array,传入readServerHandles,再将其传入 kepGroup.AsyncRead,读取数值。
7,写入数值。建立一个长度为2的value的object对象,第二位放入要写入的数值,将value变成array,传给writeArrayHandles。
总结,读取最重要的是readServerHandles,它是由增加group的Items时,向服务器传入opclist的名称和长度得来。
写入最重要的是writeArrayHandles,它是由对象value组成,value中有两个元素,第二个元素放入需要修改的值。
Dns.GetHostEntry 通过主机名解析IP地址。返回的iphost可以使用
IPhost.AddressList获得本地网卡地址,再用
(item.AddressFamily == AddressFamily.InterNetwork)得到ip4,再使用.HostName得到主机名
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;
using System.Net.Sockets;
using OPCAutomation;
using System.Collections;
namespace MyOPC
{
class Program
{
static List<OpcItem2> opcList = new List<OpcItem2>();
static void Main(string[] args)
{
IPHostEntry IPhost = Dns.GetHostEntry(Dns.GetHostName());
foreach (var item in IPhost.AddressList) //IPhost.AddressList包含了主机中网卡的地址
{
if (item.AddressFamily == AddressFamily.InterNetwork) //判断是否为ip4
{
//Console.WriteLine(Dns.GetHostEntry(item).HostName);
}
}
//定义OPC服务器;
OPCServer kepServer;
//定义OPC服务器Groups;
OPCGroups kepGroups;
OPCGroup kepGroup;
OPCItems kepItems;
OPCBrowser kepBrowser;
//定义OPC变量集合
List<int> serverHandles = new List<int>();
List<int> clientHandles = new List<int>();
List<string> tempIDList = new List<string>();
List<string> listItems = 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=1;
int writeTransID=1;
int readCancelID;
int writeCancelID;
bool connectstate;
kepServer = new OPCServer();
//获取kep服务器名称
object serverList = kepServer.GetOPCServers(Dns.GetHostName());
Array arr1 = serverList as Array;
List<string> arr2 = new List<string>();
ArrayList arr3 = new ArrayList();
foreach (string item in arr1)
{
arr3.Add(item);
arr2.Add(item);
//Console.WriteLine(item);
}
try
{
kepServer.Connect(arr2[1], Dns.GetHostName());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message,"连接失败");
}
kepGroups = kepServer.OPCGroups;
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();
kepBrowser.ShowLeafs(true);
//添加OPC服务器中的所有变量到listItems中
listItems.Clear();
foreach (var item in kepBrowser)
{
listItems.Add(item.ToString());
}
tempIDList.Clear();
clientHandles.Clear();
tempIDList.Add("0");
clientHandles.Add(0);
//foreach (string item in listItems)
//{
// Console.WriteLine(item);
//}
string strSelect = "MDbus.Modbus.K4";
opcList.Add(new OpcItem2
{
Tag = strSelect
});
int count = opcList.Count;
for (int i = 0; i < count; i++)
{
tempIDList.Add(opcList[i].Tag);
clientHandles.Add(i + 1);
}
strTempIDs = (Array)tempIDList.ToArray();
strClientHandles = (Array)clientHandles.ToArray();
kepItems = kepGroup.OPCItems;
//kepGroup中的KepItems添加标签
//strTempID就是opcList[i]中的Tag属性,clientHandles从1开始,
kepItems.AddItems(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)));//读取的strServerHandles+1
}
readServerHandles = (Array)serverHandles.ToArray();
//执行后,Value才有数值
if (opcList.Count > 0)
{
if (kepServer != null)
{
kepGroup.AsyncRead(opcList.Count, ref readServerHandles, out readError, readTransID, out readCancelID);
}
}
//判断OPC是否正在运行
if (kepServer.ServerState==(int)OPCServerState.OPCRunning)
{
connectstate = true;
}
//解析读取的OPC值
int v1 = Convert.ToInt32(opcList[0].Value);
string v0;
v0 = opcList[0].Value;
Console.WriteLine(v0);
Console.ReadKey();
//try
//{
// v0 = opcList[0].Value;
//}
//catch (Exception ex)
//{
// Console.WriteLine("赋值失败", ex);
// Console.ReadKey();
//}
int index = 0;
int[] serverHandle = new int[] { 0, Convert.ToInt32(strServerHandles.GetValue(index + 1)) };
writeServerHandles = (Array)serverHandle;
object[] values = new object[2];
values[0] = null;
values[1] = "1111";//1为异步
writeArrayHandles = (Array)values;
kepGroup.AsyncWrite(1, writeServerHandles, writeArrayHandles,out writeError, writeTransID, out writeCancelID);
//kepGroup.SyncWrite(1, ref writeServerHandles, ref writeArrayHandles, out writeError);
}
//使用委托, 并向opcList中赋值
private static 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)
{
opcList[i - 1].Value = Value.ToString();
opcList[i - 1].Time = Convert.ToDateTime(TimeStamps.GetValue(i));
}
}
}
}
}