OPC客户端抓数据

来源:互联网 发布:手机支付软件排名 编辑:程序博客网 时间:2024/05/15 07:34
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using REF.ISS.ElectricPower.BLL;using REF.ISS.ElectricPower.BLL.Models;using OPCAutomation;using System.Diagnostics;namespace REF.ISS.ElectricPower.DataCrawl{    class Program    {        static ElectricPowerDBEntities db = new ElectricPowerDBEntities();        static void Main(string[] args)        {            ThreadStart _readData = new ThreadStart(readData);            Thread ConstrolreadData = new Thread(_readData);            ThreadStart _CpuMonitor = new ThreadStart(CpuMonitor);            Thread ConstrolCpuMonitor = new Thread(_CpuMonitor);            //Stopwatch watch = new Stopwatch();            //watch.Start();             ConstrolreadData.Start();            ConstrolCpuMonitor.Start();            // GetCurrentProcessInfo();         }          static private void readData()        {            Console.WriteLine("测试OPC数据");            Start();            Console.Read();         }        static OPCServer KepServer;        static OPCGroups KepGroups;        static OPCGroup KepGroup;        static OPCItems KepItems;        static DateTime time;        static System.Timers.Timer myTimer;        static List<int> Items = new List<int>();                /// <summary>        /// OPC服务器        /// 开始抓取OPC数据        /// </summary>        static public void Start()        {            try            {                KepServer = new OPCServer();                string serverId = System.Configuration.ConfigurationManager.AppSettings["serverId"];                string serverName = System.Configuration.ConfigurationManager.AppSettings["serverName"];                KepServer.Connect(serverName, serverId);                //判断连接状态                if (KepServer.ServerState == (int)OPCServerState.OPCRunning)                {                    SendMsg("已连接到-" + KepServer.ServerName);                }                else                {                    SendMsg("状态" + KepServer.ServerState.ToString());                    return;                }                KepGroups = KepServer.OPCGroups;                Task.Factory.StartNew(CreateGroup);            }            catch (Exception e)            {                System.IO.File.AppendAllText("D:\\connect.txt", "------------连接出错 " + DateTime.Now + "--------------" + "\r\n", System.Text.Encoding.Default);                System.IO.File.AppendAllText("D:\\connect.txt", e + "\r\n", System.Text.Encoding.Default);                throw e;            }        }        /// <summary>        /// 公共函数        /// </summary>        /// <param name="m"></param>        static private void SendMsg(string m)        {            Console.Write("\n");            Console.WriteLine(m);        }        /// <summary>        /// 创建组        /// </summary>        static private void CreateGroup()        {            try            {                KepGroups = KepServer.OPCGroups;                KepGroup = KepGroups.Add("OpcGroup");                SetGroupProperty();                //KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);                KepGroup.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(GroupAsyncReadComplete);  //隔个几秒就读到所有的数据                 KepItems = KepGroup.OPCItems;                AddOpcItem();                //异步读所有数据                 myTimer = new System.Timers.Timer(3000); //周期3秒                myTimer.Elapsed += myTimer_Elapsed; //到了3秒时做的事情                myTimer.AutoReset = true; //是否不断重复定时器操作                myTimer.Enabled = true;            }            catch (Exception e)            {                System.IO.File.AppendAllText("D:\\group.txt", "------------创建组出错 " + DateTime.Now + "--------------" + "\r\n", System.Text.Encoding.Default);                System.IO.File.AppendAllText("D:\\group.txt", e + "\r\n", System.Text.Encoding.Default);                SendMsg("OPC创建组出现错误:" + e.Message);            }        }        /// <summary>        /// Timer 到了时间3秒后执行的方法        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        static private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)        {            Array serverHandles = Items.ToArray();            Array Errors;            int cancelID;            KepGroup.AsyncRead(Items.Count - 1, ref serverHandles, out Errors, 1, out cancelID);//第一参数为item数量         }           /// <summary>        /// 设置采集属性        /// 设置组属性        /// </summary>        static private void SetGroupProperty()        {            KepServer.OPCGroups.DefaultGroupIsActive = true; //激活组            KepServer.OPCGroups.DefaultGroupDeadband = 0; //死区值,设为0时,服务器端该组内任何数据变化都通知组。            KepGroup.UpdateRate = 3000; //刷新频率为3秒。            KepGroup.IsActive = true;            KepGroup.IsSubscribed = true; //使用订阅功能,即可以异步,默认false        }        /// <summary>        /// 把需要采集数据的点加进去        /// </summary>        static private void AddOpcItem()        {            try  //大小写出错时            {                var tags = db.BaseInfo.Where(t => (t.FloorNum == 1)).ToList(); //1号楼要读的电表                //var tags= db.BaseInfo.Where(t => (t.FloorNum == 2)).ToList(); //2号楼要读的电表                Items.Add(0);                for (int i = 0; i < tags.Count; i++)                {                    KepItems.AddItem(tags[i].Tag, tags[i].ID);                    Items.Add(KepItems.AddItem(tags[i].Tag, tags[i].ID).ServerHandle);                }              }             catch (Exception e)            {                System.IO.File.AppendAllText("D:\\item.txt", "------------添加item时出错 " + DateTime.Now + "--------------" + "\r\n", System.Text.Encoding.Default);                System.IO.File.AppendAllText("D:\\item.txt", e + "\r\n", System.Text.Encoding.Default);                SendMsg("添加item时出现错误:" + e.Message);            }        }        #region 数据发生变化时 执行的方法         /// <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>        static private void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)        {            time = DateTime.Now;            try            {                List<ElecValue> datas = new List<ElecValue>();                var tags = db.BaseInfo.Where(t => (t.FloorNum == 1)).ToList(); // 1 号楼 / 2 号楼                List<int> catchDataId = new List<int>();                for (int i = 1; i <= NumItems; i++)                {                    string temp = string.Concat(ClientHandles.GetValue(i), "---", ItemValues.GetValue(i), "---", Convert.ToDateTime(TimeStamps.GetValue(i)).AddHours(8).ToString());                    ElecValue data = new ElecValue();                    data.BaseInfo_ID = int.Parse(string.Concat(ClientHandles.GetValue(i)));                    data.Value = int.Parse(string.Concat(ItemValues.GetValue(i)));                    //data.Time = Convert.ToDateTime(TimeStamps.GetValue(i)).AddHours(8);                    data.Time = time;                    catchDataId.Add(data.BaseInfo_ID);                    datas.Add(data);                    // System.IO.File.AppendAllText(Server.MapPath("~/token.txt"), e + "\r\n" + DateTime.Now + "\r\n");                    System.IO.File.AppendAllText("D:\\test.txt", temp + "\r\n", System.Text.Encoding.Default);                    //db.TestData.Add(data);                    //db.SaveChanges();                      SendMsg(temp);                }                if (NumItems < tags.Count)  //当下一步没有全部传过来数据时                {                    List<int> baseInfoId = new List<int>();                    foreach (var item in tags)                    {                        baseInfoId.Add(item.ID);                    }                    var differentsValue = baseInfoId.Except(catchDataId);                    foreach (var item in differentsValue)                    {                        var val = db.ElecValue.Where(t => (t.BaseInfo_ID == item)).ToList().Last();                        datas.Add(new ElecValue()                        {                            BaseInfo_ID = item,                            Value = val.Value,                            Time = time                        });                    }                }                BatchData(datas);            }            catch (Exception e)  //空格出错            {                System.IO.File.AppendAllText("D:\\data.txt", "------------数据保存时出错 " + DateTime.Now + "--------------" + "\r\n", System.Text.Encoding.Default);                System.IO.File.AppendAllText("D:\\data.txt", e + "\r\n", System.Text.Encoding.Default);                SendMsg("数据保存时出现错误:" + e.Message);                             }        }        #endregion        /// <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>        static private 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)        {            time = DateTime.Now;             try            {                List<ElecValue> datas = new List<ElecValue>();                for (int i = 1; i <= NumItems; i++)                {                    string temp = string.Concat(ClientHandles.GetValue(i), "---", ItemValues.GetValue(i), "---", Convert.ToDateTime(TimeStamps.GetValue(i)).AddHours(8).ToString());                    ElecValue data = new ElecValue();                    data.BaseInfo_ID = int.Parse(string.Concat(ClientHandles.GetValue(i)));                    data.Value = int.Parse(string.Concat(ItemValues.GetValue(i)));                    data.Time = time;                    datas.Add(data);                       // System.IO.File.AppendAllText(Server.MapPath("~/token.txt"), e + "\r\n" + DateTime.Now + "\r\n");                    System.IO.File.AppendAllText("D:\\test.txt", temp + "\r\n", System.Text.Encoding.Default);                                        //SendMsg(temp);                }                 BatchData(datas); //批量的插入              }            catch (Exception e)            {                System.IO.File.AppendAllText("D:\\data.txt", "------------数据保存时出错 " + DateTime.Now + "--------------" + "\r\n", System.Text.Encoding.Default);                System.IO.File.AppendAllText("D:\\data.txt", e + "\r\n", System.Text.Encoding.Default);                SendMsg("数据保存时出现错误:" + e.Message);            }        }                  //批量插入数据        static void BatchData(List<ElecValue> datas)        {            db.ElecValue.AddRange(datas);            db.SaveChanges();        }        /// <summary>        /// 获取当前进程信息        /// </summary>        static private void GetCurrentProcessInfo()        {            Process cur = Process.GetCurrentProcess();            //当前进程的id            Console.WriteLine(cur.Id);            //获取关联的进程的终端服务会话标识符。            Console.WriteLine(cur.SessionId);            //当前进程的名称            Console.WriteLine(cur.ProcessName);            //当前进程的启动时间            Console.WriteLine(cur.StartTime);            //获取关联进程终止时指定的值,在退出事件中使用            //Console.WriteLine(cur.ExitCode);            //获取进程的当前机器名称            Console.WriteLine(cur.MachineName); //.代表本地            Console.WriteLine(cur.MainWindowTitle); //获取进程的主窗口标题。        }                 static private void CpuMonitor()        {             //获取当前进程对象            Process cur = Process.GetCurrentProcess();            PerformanceCounter curpcp = new PerformanceCounter("Process", "Working Set - Private", cur.ProcessName);            PerformanceCounter curpc = new PerformanceCounter("Process", "Working Set", cur.ProcessName);            PerformanceCounter curtime = new PerformanceCounter("Process", "% Processor Time", cur.ProcessName);            //上次记录CPU的时间            TimeSpan prevCpuTime = TimeSpan.Zero;            //Sleep的时间间隔            int interval = 3000;              PerformanceCounter totalcpu = new PerformanceCounter("Processor", "% Processor Time", "_Total");            SystemInfo sys = new SystemInfo();            const int KB_DIV = 1024;            const int MB_DIV = 1024 * 1024;            const int GB_DIV = 1024 * 1024 * 1024;            try            {                while (true)                {                    #region 获取CPU 内存的方法                      ////第一种方法计算CPU使用率                     ////当前时间                    //TimeSpan curCpuTime = cur.TotalProcessorTime;                    ////计算                    //double value = (curCpuTime - prevCpuTime).TotalMilliseconds / interval / Environment.ProcessorCount * 100;                    //prevCpuTime = curCpuTime;                    ////Console.WriteLine("{0}:{1}  {2:N}KB CPU使用率:{3}", cur.ProcessName, "工作集(进程类)", cur.WorkingSet64 / 1024, value);//这个工作集只是在一开始初始化,后期不变                    //// Console.WriteLine("{0}:{1}  {2:N}KB CPU使用率:{3}", cur.ProcessName, "工作集        ", curpc.NextValue() / 1024, value);//这个工作集是动态更新的                    ////第二种计算CPU使用率的方法                    //Console.WriteLine("{0}:{1}  {2:N}KB CPU使用率:{3}%", cur.ProcessName, "私有工作集    ", curpcp.NextValue() / 1024, curtime.NextValue() / Environment.ProcessorCount);                     //Thread.Sleep(interval);                     //////第一种方法获取系统CPU使用情况                    ////Console.Write("\r系统CPU使用率11:{0}%", totalcpu.NextValue());                    ////Thread.Sleep(interval);                    ////第二种方法获取系统CPU和内存使用情况                     //Console.Write("\r\n系统CPU使用率:{0}%,系统内存使用大小:{1}MB({2}GB)({3}KB)", sys.CpuLoad, (sys.PhysicalMemory - sys.MemoryAvailable) / MB_DIV, (sys.PhysicalMemory - sys.MemoryAvailable) / (double)GB_DIV, (sys.PhysicalMemory - sys.MemoryAvailable) / KB_DIV);                       //Console.WriteLine("");                        //Thread.Sleep(interval);                     #endregion                    ElecCpuMemory cpuM = new ElecCpuMemory();                    cpuM.ProCpu = curtime.NextValue() / Environment.ProcessorCount;                    cpuM.ProMemory = curpcp.NextValue() / 1024;                    cpuM.SysCpu = sys.CpuLoad;                    cpuM.SysMemory = (sys.PhysicalMemory - sys.MemoryAvailable) / KB_DIV;                    cpuM.Time = DateTime.Now;                    db.ElecCpuMemory.Add(cpuM);                    db.SaveChanges();                    Thread.Sleep(interval);                }            }            catch (Exception e)            {                System.IO.File.AppendAllText("D:\\cpu.txt", "------------CPU和内存数据保存时出错 " + DateTime.Now + "--------------" + "\r\n", System.Text.Encoding.Default);                System.IO.File.AppendAllText("D:\\cpu.txt", e + "\r\n", System.Text.Encoding.Default);                                 SendMsg("CPU和内存数据保存时出现错误:" + e.Message);            }        }    }}
----------------------------------------------------------------------------------
using System;using System.Collections.Generic;using System.Diagnostics;using System.Threading;using System.IO;using System.Text;using System.Management;using System.Runtime.InteropServices; namespace REF.ISS.ElectricPower.DataCrawl{    public class SystemInfo    {        private int m_ProcessorCount = 0;   //CPU个数        private PerformanceCounter pcCpuLoad;   //CPU计数器        private long m_PhysicalMemory = 0;   //物理内存         private const int GW_HWNDFIRST = 0;        private const int GW_HWNDNEXT = 2;        private const int GWL_STYLE = (-16);        private const int WS_VISIBLE = 268435456;        private const int WS_BORDER = 8388608;         #region AIP声明        [DllImport("IpHlpApi.dll")]        extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder);         [DllImport("User32")]        private extern static int GetWindow(int hWnd, int wCmd);         [DllImport("User32")]        private extern static int GetWindowLongA(int hWnd, int wIndx);         [DllImport("user32.dll")]        private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize);         [DllImport("user32", CharSet = CharSet.Auto)]        private extern static int GetWindowTextLength(IntPtr hWnd);        #endregion         #region 构造函数        /// <summary>        /// 构造函数,初始化计数器等        /// </summary>        public SystemInfo()        {            //初始化CPU计数器            pcCpuLoad = new PerformanceCounter("Processor""% Processor Time""_Total");            pcCpuLoad.MachineName = ".";            pcCpuLoad.NextValue();             //CPU个数            m_ProcessorCount = Environment.ProcessorCount;             //获得物理内存            ManagementClass mc = new ManagementClass("Win32_ComputerSystem");            ManagementObjectCollection moc = mc.GetInstances();            foreach (ManagementObject mo in moc)            {                if (mo["TotalPhysicalMemory"] != null)                {                    m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString());                }            }        }        #endregion         #region CPU个数        /// <summary>        /// 获取CPU个数        /// </summary>        public int ProcessorCount        {            get            {                return m_ProcessorCount;            }        }        #endregion         #region CPU占用率        /// <summary>        /// 获取CPU占用率        /// </summary>        public float CpuLoad        {            get            {                return pcCpuLoad.NextValue();            }        }        #endregion         #region 可用内存        /// <summary>        /// 获取可用内存        /// </summary>        public long MemoryAvailable        {            get            {                long availablebytes = 0;                //ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfRawData_PerfOS_Memory");                //foreach (ManagementObject mo in mos.Get())                //{                //    availablebytes = long.Parse(mo["Availablebytes"].ToString());                //}                ManagementClass mos = new ManagementClass("Win32_OperatingSystem");                foreach (ManagementObject mo in mos.GetInstances())                {                    if (mo["FreePhysicalMemory"] != null)                    {                        availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString());                    }                }                return availablebytes;            }        }        #endregion         #region 物理内存        /// <summary>        /// 获取物理内存        /// </summary>        public long PhysicalMemory        {            get            {                return m_PhysicalMemory;            }        }        #endregion         #region 结束指定进程        /// <summary>        /// 结束指定进程        /// </summary>        /// <param name="pid">进程的 Process ID</param>        public static void EndProcess(int pid)        {            try            {                Process process = Process.GetProcessById(pid);                process.Kill();            }            catch { }        }        #endregion          #region 查找所有应用程序标题        /// <summary>        /// 查找所有应用程序标题        /// </summary>        /// <returns>应用程序标题范型</returns>        public static List<string> FindAllApps(int Handle)        {            List<string> Apps = new List<string>();             int hwCurr;            hwCurr = GetWindow(Handle, GW_HWNDFIRST);             while (hwCurr > 0)            {                int IsTask = (WS_VISIBLE | WS_BORDER);                int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE);                bool TaskWindow = ((lngStyle & IsTask) == IsTask);                if (TaskWindow)                {                    int length = GetWindowTextLength(new IntPtr(hwCurr));                    StringBuilder sb = new StringBuilder(2 * length + 1);                    GetWindowText(hwCurr, sb, sb.Capacity);                    string strTitle = sb.ToString();                    if (!string.IsNullOrEmpty(strTitle))                    {                        Apps.Add(strTitle);                    }                }                hwCurr = GetWindow(hwCurr, GW_HWNDNEXT);            }              return Apps;        }        #endregion         }}
-----------------------------------------
  <appSettings>    <add key ="serverId" value="192.168.1.22" />    <add key="serverName" value="Matrikon.OPC.Simulation.1" />  </appSettings>

 
原创粉丝点击