using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections;
using OPCAutomation;
using System.Threading;
namespace OPCDAAutoTest
{
class Tester
{
static void Main(string[] args)
{
Tester tester=new Tester();
tester.work();
}
#region 私有變量
/// <summary>
/// OPCServer Object
/// </summary>
OPCServer MyServer;
/// <summary>
/// OPCGroups Object
/// </summary>
OPCGroups MyGroups;
/// <summary>
/// OPCGroup Object
/// </summary>
OPCGroup MyGroup;
OPCGroup MyGroup2;
/// <summary>
/// OPCItems Object
/// </summary>
OPCItems MyItems;
OPCItems MyItems2;
/// <summary>
/// OPCItem Object
/// </summary>
OPCItem[] MyItem;
OPCItem[] MyItem2;
/// <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
//測試用工作方法
public void work()
{
//初始化item數組
MyItem = new OPCItem[4];
MyItem2 = new OPCItem[4];
GetLocalServer();
//ConnectRemoteServer("TX1", "KEPware.KEPServerEx.V4");//用計算機名的局域網
//ConnectRemoteServer("192.168.1.35", "KEPware.KEPServerEx.V4");//用IP的局域網
if (ConnectRemoteServer("", "KEPware.KEPServerEx.V4"))//本機
{
if (CreateGroup())
{
Thread.Sleep(500);//暫停線程以讓DataChange反映,否則下面的同步讀可能讀不到
//以下同步寫
MyItem[3].Write("I love you!");//同步寫
MyItem[2].Write(true);//同步寫
MyItem[1].Write(-100);//同步寫
MyItem[0].Write(120);//同步寫
//以下同步讀
object ItemValues; object Qualities; object TimeStamps;//同步讀的臨時變量:值、質量、時間戳
MyItem[0].Read(1,out ItemValues,out Qualities,out TimeStamps);//同步讀,第一個參數只能爲1或2
int q0 = Convert.ToInt32(ItemValues);//轉換後獲取item值
MyItem[1].Read(1, out ItemValues, out Qualities, out TimeStamps);//同步讀,第一個參數只能爲1或2
int q1 = Convert.ToInt32(ItemValues);//轉換後獲取item值
MyItem[2].Read(1, out ItemValues, out Qualities, out TimeStamps);//同步讀,第一個參數只能爲1或2
bool q2 = Convert.ToBoolean(ItemValues);//轉換後獲取item值
MyItem[3].Read(1, out ItemValues, out Qualities, out TimeStamps);//同步讀,第一個參數只能爲1或2
string q3 = Convert.ToString(ItemValues);//轉換後獲取item值,爲防止讀到的值爲空,不用ItemValues.ToString()
Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Console.WriteLine("0-{0},1-{1},2-{2},3-{3}",q0,q1,q2,q3);
//以下爲異步寫
//異步寫時,Array數組從下標1開始而非0!
int[] temp = new int[] { 0,MyItem[0].ServerHandle,MyItem[1].ServerHandle,MyItem[2].ServerHandle, MyItem[3].ServerHandle };
Array serverHandles = (Array)temp;
object[] valueTemp = new object[5] { "",255,520,true, "Love" };
Array values = (Array)valueTemp;
Array Errors;
int cancelID;
MyGroup.AsyncWrite(4, ref serverHandles, ref values, out Errors, 1, out cancelID);//第一參數爲item數量
//由於MyGroup2沒有訂閱,所以以下這句運行時將會出錯!
//MyGroup2.AsyncWrite(4, ref serverHandles, ref values, out Errors, 1, out cancelID);
//以下異步讀
MyGroup.AsyncRead(4, ref serverHandles, out Errors, 1, out cancelID);//第一參數爲item數量
/*MyItem[0] = MyItems.AddItem("BPJ.Db1.dbb96", 0);//byte
MyItem[1] = MyItems.AddItem("BPJ.Db1.dbw10", 1);//short
MyItem[2] = MyItems.AddItem("BPJ.Db16.dbx0", 2);//bool
MyItem[3] = MyItems.AddItem("BPJ.Db11.S0", 3);//string*/
Console.WriteLine("************************************** hit <return> to Disconnect...");
Console.ReadLine();
//釋放所有組資源
MyServer.OPCGroups.RemoveAll();
//斷開服務器
MyServer.Disconnect();
}
}
//END
Console.WriteLine("************************************** hit <return> to close...");
Console.ReadLine();
}
//枚舉本地OPC服務器
private void GetLocalServer()
{
//獲取本地計算機IP,計算機名稱
strHostName = Dns.GetHostName();
//或者通過局域網內計算機名稱
strHostName = "TX1";
//獲取本地計算機上的OPCServerName
try
{
MyServer = new OPCServer();
object serverList = MyServer.GetOPCServers(strHostName);
foreach (string server in (Array)serverList)
{
//cmbServerName.Items.Add(turn);
Console.WriteLine("本地OPC服務器:{0}", server);
}
}
catch (Exception err)
{
Console.WriteLine("枚舉本地OPC服務器出錯:{0}",err.Message);
}
}
//連接OPC服務器
/// <param name="remoteServerIP">OPCServerIP</param>
/// <param name="remoteServerName">OPCServer名稱</param>
private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)
{
try
{
MyServer.Connect(remoteServerName, remoteServerIP);//連接本地服務器:服務器名+主機名或IP
if (MyServer.ServerState == (int)OPCServerState.OPCRunning)
{
Console.WriteLine("已連接到:{0}",MyServer.ServerName);
}
else
{
//這裏你可以根據返回的狀態來自定義顯示信息,請查看自動化接口API文檔
Console.WriteLine("狀態:{0}",MyServer.ServerState.ToString());
}
MyServer.ServerShutDown+=ServerShutDown;//服務器斷開事件
}
catch (Exception err)
{
Console.WriteLine("連接遠程服務器出現錯誤:{0}" + err.Message);
return false;
}
return true;
}
//創建組
private bool CreateGroup()
{
try
{
MyGroups = MyServer.OPCGroups;
MyGroup = MyServer.OPCGroups.Add("測試");//添加組
MyGroup2 = MyGroups.Add("測試2");
OPCGroup MyGroup3 = MyGroups.Add("測試3");//測試刪除組
//以下設置組屬性
{
MyServer.OPCGroups.DefaultGroupIsActive = true;//激活組。
MyServer.OPCGroups.DefaultGroupDeadband = 0;// 死區值,設爲0時,服務器端該組內任何數據變化都通知組。
MyServer.OPCGroups.DefaultGroupUpdateRate = 200;//默認組羣的刷新頻率爲200ms
MyGroup.UpdateRate = 100;//刷新頻率爲1秒。
MyGroup.IsSubscribed = true;//使用訂閱功能,即可以異步,默認false
}
MyGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange);
MyGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(GroupAsyncWriteComplete);
MyGroup.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(GroupAsyncReadComplete);
//由於MyGroup2.IsSubscribed是false,即沒有訂閱,所以以下的DataChange回調事件不會發生!
MyGroup2.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(GroupDataChange2);
MyGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(GroupAsyncWriteComplete);
MyServer.OPCGroups.Remove("測試3");//移除組
AddGroupItems();//設置組內items
}
catch (Exception err)
{
Console.WriteLine("創建組出現錯誤:{0}", err.Message);
return false;
}
return true;
}
private void AddGroupItems()//添加組
{
//itmHandleServer;
MyItems = MyGroup.OPCItems;
MyItems2 = MyGroup2.OPCItems;
//添加item
MyItem[0] = MyItems.AddItem("BPJ.Db1.dbb96", 0);//byte
MyItem[1] = MyItems.AddItem("BPJ.Db1.dbw10", 1);//short
MyItem[2] = MyItems.AddItem("BPJ.Db16.dbx0", 2);//bool
MyItem[3] = MyItems.AddItem("BPJ.Db11.S0", 3);//string
//移除組內item
Array Errors;
int []temp=new int[]{0,MyItem[3].ServerHandle};
Array serverHandle = (Array)temp;
MyItems.Remove(1, ref serverHandle, out Errors);
MyItem[3] = MyItems.AddItem("BPJ.Db11.S0", 3);//string
MyItem2[0] = MyItems2.AddItem("BPJ.Db1.dbb96", 0);//byte
MyItem2[1] = MyItems2.AddItem("BPJ.Db1.dbw10", 1);//short
MyItem2[2] = MyItems2.AddItem("BPJ.Db16.dbx0", 2);//bool
MyItem2[3] = MyItems2.AddItem("BPJ.Db11.S0", 3);//string
}
public void ServerShutDown(string Reason)//服務器先行斷開
{
Console.WriteLine("服務器已經先行斷開!");
}
/// <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>1 `
void GroupDataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
Console.WriteLine("++++++++++++++++DataChanged+++++++++++++++++++++++");
/*for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("item值:{0}", ItemValues.GetValue(i).ToString());
//Console.WriteLine("item句柄:{0}", ClientHandles.GetValue(i).ToString());
//Console.WriteLine("item質量:{0}", Qualities.GetValue(i).ToString());
//Console.WriteLine("item時間戳:{0}", TimeStamps.GetValue(i).ToString());
//Console.WriteLine("item類型:{0}", ItemValues.GetValue(i).GetType().FullName);
}*/
}
void GroupDataChange2(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
Console.WriteLine("----------------------DataChanged2------------------");
/*for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("item2值:{0}", ItemValues.GetValue(i).ToString());
//Console.WriteLine("item2質量:{0}", Qualities.GetValue(i).ToString());
//Console.WriteLine("item2時間戳:{0}", TimeStamps.GetValue(i).ToString());
}*/
}
/// <summary>
/// 異步寫完成
/// 運行時,Array數組從下標1開始而非0!
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="Errors"></param>
void GroupAsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)
{
Console.WriteLine("%%%%%%%%%%%%%%%%AsyncWriteComplete%%%%%%%%%%%%%%%%%%%");
/*for (int i = 1; i <= NumItems; i++)
{
Console.WriteLine("Tran:{0} ClientHandles:{1} Error:{2}", TransactionID.ToString(), ClientHandles.GetValue(i).ToString(), Errors.GetValue(i).ToString());
}*/
}
/// <summary>
/// 異步讀完成
/// 運行時,Array數組從下標1開始而非0!
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="ItemValues"></param>
/// <param name="Qualities"></param>
/// <param name="TimeStamps"></param>
/// <param name="Errors"></param>
void GroupAsyncReadComplete(int TransactionID, int NumItems, ref System.Array ClientHandles, ref System.Array ItemValues, ref System.Array Qualities, ref System.Array TimeStamps, ref System.Array Errors)
{
Console.WriteLine("****************GroupAsyncReadComplete*******************");
for (int i = 1; i <= NumItems; i++)
{
//Console.WriteLine("Tran:{0} ClientHandles:{1} Error:{2}", TransactionID.ToString(), ClientHandles.GetValue(i).ToString(), Errors.GetValue(i).ToString());
Console.WriteLine("Vaule:{0}",Convert.ToString(ItemValues.GetValue(i)));
}
}
}
}