OPC学习

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值