天天看點

用C#開發OPC用戶端

///鄙視那些拿代碼當寶貝的人,鄙視那些拿源碼換源碼的人,鄙視那些自私的人。

///别人看到你的代碼,你能死啊?對你有多大威脅啊?強烈鄙視~~~

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Net;

using System.Collections;

using OPCAutomation;

namespace OPC測試通過

{

    public partial class MainFrom : Form

    {

        public MainFrom()

        {

            InitializeComponent();

        }

        #region 私有變量

        /// <summary>

        /// OPCServer Object

        /// </summary>

        OPCServer KepServer;

        /// OPCGroups Object

        OPCGroups KepGroups;

        /// OPCGroup Object

        OPCGroup KepGroup;

        /// OPCItems Object

        OPCItems KepItems;

        /// OPCItem Object

        OPCItem KepItem;

        /// 主機IP

        string strHostIP = "";

        /// 主機名稱

        string strHostName = "";

        /// 連接配接狀态

        bool opc_connected = false;

        /// 用戶端句柄

        int itmHandleClient = 0;

        /// 服務端句柄

        int itmHandleServer = 0;

        #endregion

        #region 方法

        /// 枚舉本地OPC伺服器

        private void GetLocalServer()

            //擷取本地計算機IP,計算機名稱

            IPHostEntry IPHost = Dns.Resolve(Environment.MachineName);

            if (IPHost.AddressList.Length > 0)

            {

                strHostIP = IPHost.AddressList[0].ToString();

            }

            else

                return;

            //通過IP來擷取計算機名稱,可用在區域網路内

            IPHostEntry ipHostEntry = Dns.GetHostByAddress(strHostIP);

            strHostName=ipHostEntry.HostName.ToString();

            //擷取本地計算機上的OPCServerName

            try

                KepServer = new OPCServer();

                object serverList = KepServer.GetOPCServers(strHostName);

                foreach (string turn in (Array)serverList)

                {

                    cmbServerName.Items.Add(turn);

                }

                cmbServerName.SelectedIndex = 0;

                btnConnServer.Enabled = true;

            catch(Exception err)

                MessageBox.Show("枚舉本地OPC伺服器出錯:"+err.Message,"提示資訊",MessageBoxButtons.OK,MessageBoxIcon.Warning);

        /// 建立組

        private bool CreateGroup()

                KepGroups = KepServer.OPCGroups;

                KepGroup = KepGroups.Add("OPCDOTNETGROUP");

                SetGroupProperty();

                KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);

                KepGroup.AsyncWriteComplete += new DIOPCGroupEvent_AsyncWriteCompleteEventHandler(KepGroup_AsyncWriteComplete);

                KepItems = KepGroup.OPCItems;

            catch (Exception err)

                MessageBox.Show("建立組出現錯誤:"+err.Message,"提示資訊",MessageBoxButtons.OK,MessageBoxIcon.Warning);

                return false;

            return true;

        /// 設定組屬性

        private void SetGroupProperty()

            KepServer.OPCGroups.DefaultGroupIsActive =Convert.ToBoolean(txtGroupIsActive.Text);

            KepServer.OPCGroups.DefaultGroupDeadband = Convert.ToInt32(txtGroupDeadband.Text);

            KepGroup.UpdateRate = Convert.ToInt32(txtUpdateRate.Text);

            KepGroup.IsActive = Convert.ToBoolean(txtIsActive.Text);

            KepGroup.IsSubscribed =Convert.ToBoolean(txtIsSubscribed.Text);

        /// 列出OPC伺服器中所有節點

        /// <param name="oPCBrowser"></param>

        private void RecurBrowse(OPCBrowser oPCBrowser)

            //展開分支

            oPCBrowser.ShowBranches();

            //展開葉子

            oPCBrowser.ShowLeafs(true);

            foreach (object turn in oPCBrowser)

                listBox1.Items.Add(turn.ToString());

        /// 擷取伺服器資訊,并顯示在窗體狀态欄上

        private void GetServerInfo()

            tsslServerStartTime.Text ="開始時間:"+ KepServer.StartTime.ToString()+"    ";

            tsslversion.Text ="版本:"+ KepServer.MajorVersion.ToString() + "." + KepServer.MinorVersion.ToString()+"."+KepServer.BuildNumber.ToString();

        /// 連接配接OPC伺服器

        /// <param name="remoteServerIP">OPCServerIP</param>

        /// <param name="remoteServerName">OPCServer名稱</param>

        private bool ConnectRemoteServer(string remoteServerIP, string remoteServerName)

                KepServer.Connect(remoteServerName, remoteServerIP);

                if (KepServer.ServerState == (int)OPCServerState.OPCRunning)

                    tsslServerState.Text = "已連接配接到-" + KepServer.ServerName + "   ";

                else

                    //這裡你可以根據傳回的狀态來自定義顯示資訊,請檢視自動化接口API文檔

                    tsslServerState.Text = "狀态:" + KepServer.ServerState.ToString() + "   ";

                MessageBox.Show("連接配接遠端伺服器出現錯誤:" + err.Message, "提示資訊", MessageBoxButtons.OK, MessageBoxIcon.Warning);

        #region 事件

        /// 寫入TAG值時執行的事件

        /// <param name="TransactionID"></param>

        /// <param name="NumItems"></param>

        /// <param name="ClientHandles"></param>

        /// <param name="Errors"></param>

        void KepGroup_AsyncWriteComplete(int TransactionID, int NumItems, ref Array ClientHandles, ref Array Errors)

            lblState.Text = "";

            for (int i = 1; i <= NumItems; i++)

                lblState.Text += "Tran:" + TransactionID.ToString() + "   CH:" + ClientHandles.GetValue(i).ToString() + "   Error:" + Errors.GetValue(i).ToString();

        /// 每當項資料有變化時執行的事件

        /// <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>

        void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)

            //為了測試,是以加了控制台的輸出,來檢視事物ID号

            //Console.WriteLine("********"+TransactionID.ToString()+"*********");

                this.txtTagValue.Text = ItemValues.GetValue(i).ToString();

                this.txtQualities.Text = Qualities.GetValue(i).ToString();

                this.txtTimeStamps.Text = TimeStamps.GetValue(i).ToString();

        /// 選擇清單項時處理的事情

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)

                if (itmHandleClient != 0)

                    this.txtTagValue.Text = "";

                    this.txtQualities.Text ="";

                    this.txtTimeStamps.Text = "";

                    Array Errors;

                    OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);

                    //注:OPC中以1為數組的基數

                    int[] temp = new int[2] { 0, bItem.ServerHandle };

                    Array serverHandle = (Array)temp;

                    //移除上一次選擇的項

                    KepItems.Remove(KepItems.Count, ref serverHandle, out Errors);

                itmHandleClient = 1234;

                KepItem = KepItems.AddItem(listBox1.SelectedItem.ToString(), itmHandleClient);

                itmHandleServer = KepItem.ServerHandle;

                //沒有任何權限的項,都是OPC伺服器保留的系統項,此處可不做處理。

                itmHandleClient = 0;

                txtTagValue.Text = "Error ox";

                txtQualities.Text = "Error ox";

                txtTimeStamps.Text = "Error ox";

                MessageBox.Show("此項為系統保留項:"+err.Message,"提示資訊");

        /// 載入窗體時處理的事情

        private void MainFrom_Load(object sender, EventArgs e)

            GetLocalServer();

        /// 關閉窗體時處理的事情

        private void MainFrom_FormClosing(object sender, FormClosingEventArgs e)

            if (!opc_connected)

            if (KepGroup != null)

                KepGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);

            if (KepServer != null)

                KepServer.Disconnect();

                KepServer = null;

            opc_connected = false;

        /// 【按鈕】設定

        private void btnSetGroupPro_Click(object sender, EventArgs e)

            SetGroupProperty();

        /// 【按鈕】連接配接OPC伺服器

        private void btnConnLocalServer_Click(object sender, EventArgs e)

                if (!ConnectRemoteServer(txtRemoteServerIP.Text,cmbServerName.Text))

                    return;

                btnSetGroupPro.Enabled = true;

                opc_connected = true;

                GetServerInfo();

                RecurBrowse(KepServer.CreateBrowser());

                if (!CreateGroup())

                MessageBox.Show("初始化出錯:" + err.Message, "提示資訊", MessageBoxButtons.OK, MessageBoxIcon.Warning);

        /// 【按鈕】寫入

        private void btnWrite_Click(object sender, EventArgs e)

            OPCItem bItem = KepItems.GetOPCItem(itmHandleServer);

            int[] temp = new int[2] { 0, bItem.ServerHandle };

            Array serverHandles=(Array)temp;

            object[] valueTemp = new object[2] {"",txtWriteTagValue.Text };

            Array values=(Array)valueTemp;

            Array Errors;

            int cancelID;

            KepGroup.AsyncWrite(1,ref serverHandles,ref values,out Errors, 2009,out cancelID);

            //KepItem.Write(txtWriteTagValue.Text);//這句也可以寫入,但并不觸發寫入事件

            GC.Collect();

    }

}

本文轉自tiasys部落格園部落格,原文連結:http://www.cnblogs.com/tiasys/archive/2009/08/30/1556908.html,如需轉載請自行聯系原作者

繼續閱讀