读取opc da 数据到mysql 怎样把opc数据写入数据库

您所在的位置:网站首页 opc读取可以数据库sql吗 读取opc da 数据到mysql 怎样把opc数据写入数据库

读取opc da 数据到mysql 怎样把opc数据写入数据库

2024-02-28 17:05| 来源: 网络整理| 查看: 265

记录一下今天刚写完并且运行成功的代码和思路,关于工业协议OPC的数据读写,还有与数据库的交互相关问题,重点是批量,如何批量进行导出导入和更新。

OPC不用讲了,工业协议,做物联网的都知道。。。。= =其实就是个DLL包,没啥东西好说的,用人家的东西就行了。从设备上把数据读出来。

其实上个星期写过一个关于门禁系统的数据交互,大概功能是从某大厦把所有门禁的数据读出来,然后更新到数据库,保留数据,供查询使用,但是上次的思路是:

从OPCExplorer或者OPC Client中连接到OPC服务,然后显示所有的点之后,把所有点位用导出导成一个ini文件

读取opc da 数据到mysql 怎样把opc数据写入数据库_物联网OPC代码C#数据库

如上图的导出,然后见到是ini文件是这样的:

读取opc da 数据到mysql 怎样把opc数据写入数据库_数据_02

在完成导出之后,根据ini文件里面的字段,自己手动建立一个mysql数据表,经过相关的整理(行转列),然后形成一张包含了OPC所有item点位信息的数据库表,然后在添加OPCitem的时候,用reader.read()(这个read()的是select from table的时候mysql的read方法,不是OPC的方法,后面提到的read()才是OPC的)来从数据库里添加,然后在用OPC的read去读,这种方法就是不直接从OPC服务端里面拿点位,是先把点位导出之后整理成数据库文件,从数据库文件里把点位添加上去,然后再读点位数据,这样如果点位不匹配的话,read()的时候OPC就会报错,因为人家服务端没有你这个点位,搜不到,也就加不上去,只有你数据库表里的所有点位跟OPC里的实际点位完全重叠,才能用这个方法,如果厂商添加了OPCitem,那就报错。

今天写的新OPC工具,目的就是为了解决OPC点位的问题,因为之前的方法不仅麻烦(从ini中手动把点位放到数据表中有大量重复工作),而且一旦点位变就会报错,还需要重新改数据库。这个OPC工具的思路就是:

全部工作在代码中完成,不需要手动去添加item数据,直接写一个代码把所有item从OPC中读出来,然后放到表中,然后读value再更新到表中,这样每次开启程序,就是先添加一遍所有点位,然后就按照设定的速率一直update数据库,这样就解决了老方法的多个问题。下面开始代码(C#):

OPCServer opcServer = new OPCServer(); OPCBrowser opcBrowser; opcServer.Connect("ICONICS.SimulatorOPCDA.2"); Console.WriteLine("连接OPC成功!"); opcBrowser = opcServer.CreateBrowser(); opcBrowser.ShowBranches(); opcBrowser.ShowLeafs(true); OPCGroups opcGroups = opcServer.OPCGroups; OPCGroup opcGroup = opcGroups.Add("HassanGroup"); OPCItems opcItems = opcGroup.OPCItems; OPCItem opcItem,opcId; Object value, qty, time;

一开始先进行OPC的初始化,这里不赘述,这里用connect的是每台终端都有的一个供实验用的OPC服务,我本机上的是

ICONICS.SimulatorOPCDA.2

,里面的数据是会变动的,跟别人没关系,只存在你自己的主机上。值得一说的是这用了Browser里面的Branches和Leafs,顾名思义这两个东西,就是枝干和叶子结点,就是遍历所有item的方法。

foreach (object turn in opcBrowser) { opcItem = opcItems.AddItem(Convert.ToString(turn), 0); opcItem.Read((short)OPCDataSource.OPCDevice, out value, out qty, out time); Console.WriteLine(opcItem.ItemID + "=" + opcItem.Value); //Console.WriteLine("连接数据库成功!"); string sql = string.Format("INSERT INTO /*建的空表名*/ (OpcService, ItemID, ItemValue)"+ "VALUES "+ "('ICONICS.SimulatorOPCDA.2', '{0}', '{1}');", opcItem.ItemID, opcItem.Value); MySqlCommand cmd = new MySqlCommand(sql, mycon); //cmd.ExecuteNonQuery(); /* MySqlCommand cmd1 = new MySqlCommand(sql1, mycon); MySqlDataReader reader = cmd1.ExecuteReader(); MySqlDataAdapter sda = new MySqlDataAdapter(sql1,mycon); DataTable dt = new DataTable(); sda.Fill(dt); Console.WriteLine(dt); */ Console.WriteLine("插入表数据成功!"); }

这部分就是怎么从OPC里找出所有的item,然后insert进一个你建好的空表,我建的这个空表有三个字段,分别是OpcService、ItemID和ItemValue,其中

OpcService这个不用动,如果你是对单个opc操作的话,基本用不上这个功能,直接设置成固定的名称就行了,ItemID就是点位的名称,主键,ItemValue是读出来的所有item的值。

while (true) { mycon.Open(); string sql = "select * from /*建的空表名*/"; MySqlCommand cmd = new MySqlCommand(sql, mycon); MySqlDataReader reader = cmd.ExecuteReader(); Console.WriteLine("查询 表数据完毕!"); while (reader.Read()) { opcId = opcGroup.OPCItems.AddItem(Convert.ToString(reader["ItemID"]), 0); opcId.Read((short)OPCDataSource.OPCDevice, out value, out qty, out time); string sql1 = String.Format("update opc_items set ItemValue='{0}'"+ "where OpcService='{1}'and ItemID='{2}'", value, reader["OpcService"], reader["ItemID"]); MySqlConnection conUpd = new MySqlConnection(connStr); conUpd.Open(); MySqlCommand cmdUpd = new MySqlCommand(sql1, conUpd); cmdUpd.ExecuteNonQuery(); conUpd.Close(); } mycon.Close(); Thread.Sleep(5000); }

这里是往表里添加完所有的点位之后,再持续从opc上读取所有点位的值,然后每5秒update一次数据表,所以写在死循环里,因为这个东西打开之后就要一直读取--更新,读取--更新,所有放着就行,自动每五秒循环一次。这部分的思路其实就是前面所提到的上周写的代码的思路,先查询一个已经存放了所有item点位的数据表,然后从表里把item添加,再放到OPC里去读值,然后回来更新原来的表,搞定!至于为什么while()里面还要再开开一次数据库,这个在前几天的博客里有一篇,目前我还没想好怎么优化这个点,以后再想办法吧。

完整代码:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using OPCAutomation; using MySql.Data; using MySql.Data.MySqlClient; using System.Configuration; using System.Data; namespace OpcTool { class Program { static void Main(string[] args) { OPCServer opcServer = new OPCServer(); OPCBrowser opcBrowser; opcServer.Connect("ICONICS.SimulatorOPCDA.2"); Console.WriteLine("连接OPC成功!"); opcBrowser = opcServer.CreateBrowser(); opcBrowser.ShowBranches(); opcBrowser.ShowLeafs(true); OPCGroups opcGroups = opcServer.OPCGroups; OPCGroup opcGroup = opcGroups.Add("**********"); OPCItems opcItems = opcGroup.OPCItems; OPCItem opcItem,opcId; Object value, qty, time; string connStr = ConfigurationManager.AppSettings["ConnectionString"]; MySqlConnection mycon = new MySqlConnection(connStr); mycon.Open(); foreach (object turn in opcBrowser) { opcItem = opcItems.AddItem(Convert.ToString(turn), 0); opcItem.Read((short)OPCDataSource.OPCDevice, out value, out qty, out time); Console.WriteLine(opcItem.ItemID + "=" + opcItem.Value); //Console.WriteLine("连接数据库成功!"); string sql = string.Format("INSERT INTO opc_items (OpcService, ItemID, ItemValue)"+ "VALUES "+ "('ICONICS.SimulatorOPCDA.2', '{0}', '{1}');", opcItem.ItemID, opcItem.Value); MySqlCommand cmd = new MySqlCommand(sql, mycon); //cmd.ExecuteNonQuery(); /* MySqlCommand cmd1 = new MySqlCommand(sql1, mycon); MySqlDataReader reader = cmd1.ExecuteReader(); MySqlDataAdapter sda = new MySqlDataAdapter(sql1,mycon); DataTable dt = new DataTable(); sda.Fill(dt); Console.WriteLine(dt); */ Console.WriteLine("插入表数据成功!"); } mycon.Close(); while (true) { mycon.Open(); string sql = "select * from opc_items"; MySqlCommand cmd = new MySqlCommand(sql, mycon); MySqlDataReader reader = cmd.ExecuteReader(); Console.WriteLine("查询opc_item表数据完毕!"); while (reader.Read()) { opcId = opcGroup.OPCItems.AddItem(Convert.ToString(reader["ItemID"]), 0); opcId.Read((short)OPCDataSource.OPCDevice, out value, out qty, out time); string sql1 = String.Format("update opc_items set ItemValue='{0}'"+ "where OpcService='{1}'and ItemID='{2}'", value, reader["OpcService"], reader["ItemID"]); MySqlConnection conUpd = new MySqlConnection(connStr); conUpd.Open(); MySqlCommand cmdUpd = new MySqlCommand(sql1, conUpd); cmdUpd.ExecuteNonQuery(); conUpd.Close(); } mycon.Close(); Thread.Sleep(5000); } Console.ReadKey(); } } }

关于物联网的实际解决问题代码和思路以后还有更新,刚入行不久,每天总结点自己学到东西,希望大家能用到,上面的代码和思路都是自己的理解,如果有不对的地方欢迎指正,共同进步!   = _+ 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3