您的位置:控制工程论坛网论坛 » 自动化软件 » 紫金桥实时数据库的应用——通过函数写入数据到关系数据库典型案例

zijinqiao

zijinqiao   |   当前状态:在线

总积分:1659  2024年可用积分:0

注册时间: 2007-01-15

最后登录时间: 2023-01-13

空间 发短消息加为好友

紫金桥实时数据库的应用——通过函数写入数据到关系数据库典型案例

zijinqiao  发表于 2018/3/6 10:44:33      932 查看 0 回复  [上一主题]  [下一主题]

手机阅读

某天然气公司的生产信息平台,是一个生产运行关键数据统计和展示的平台,其中的装置关键参数合格率、设备运行状态、振动设备报警监测这三部分,由紫金桥实时数据库提供数据。

客户在功能上要求是这样的:

1、装置关键参数合格率,报警上下限值要从指定的关系数据库表中读取,该表由工艺人员根据需要修改报警上下限的限值,紫金桥软件根据此限值计算装置关键参数的合格率,计算完成后,再存入关系数据库指定的表中。

2、设备运行状态,实时值由信息平台实时读取,历史值要定时存入关系数据库指定的表中。

3、设备振动报警监测,实时值由信息平台实时读取,不需要存储历史值。

 

设备运行状态以及设备振动监测的实时数据是通过开放OPC Server接口,由对方直接实时采集,装置关键参数的合格率以及设备运行状态历史两部分的数据,是通过紫金桥实时数据库软件,将历史数据写入到SQL Server数据库中,再由生产信息平台系统从SQL Server中按照需要读取。

系统使用的软件版本:紫金桥实时数据库软件V6.5

功能窗口截图如下,由于该窗口不需要展示,故未做任何美化:

各部分功能说明:

 

1-报警时间统计组件,用于统计位号的累计报警时间,以便计算合格率。

2-设备状态实时报表,实时显示设备状态值,通过脚本将对应位号的值存储到数据库中。

3-位号的报警上下限值报表,从关系数据库读取参数的报警限值。

4-手动读取合格率报警限值按钮,点击后读取关系数据库的报警限值。

5-查看当天已经写入数据的报表,用来查看数据库中已经写入的数据。

6-查看设备状态/合格率数据按钮。点击按钮分别查看最近一天的设备状态或者合格率数据。

  窗口最下方的部分即56两块实际上不是功能必须的,只是方便开发者自己查看远程数据库中的数据是否成功存储。

 

本文主要介绍“装置关键参数合格率”这部分的功能,“设备运行状态”部分大同小异,“设备振动监测”部分不需要向关系数据库存储数据,所以这两部分不再过多叙述。

 

接下来开始说明关键参数合格率功能部分:

 

1、窗口中新增报警时间统计组件,命名为Alarm1,在组件中添加需要进行统计的位号,设置位号使用自身报警限值。

 

2、点组态中,新增‘报表关系数据源点’,连接要读取数据的关系数据库。

 

3、窗口中新增自由报表,关系数据库连接里面,连接新建的报表关系数据源点,并将报表命名。本案例中,该报表名为Fr1 

 

4、建立表模板。

使用紫金桥软件预定义的SQL函数向关系数据库插入数据,首先要按照固定表结构在关系数据库先创建表, SQL函数无法直接生成表,而是需要一个给定的模板,按照模板进行表的创建,这就需要事先定义好一个表模板。

下图是合格率数据表要使用的表模板,要创建的表一共有4个字段,分别是‘日期、位号名、值、权重’,对应的字段名分别是‘UpdateTimeTagNameTagValueTagLevel’,权重这个字段是客户要求的。


合格率表模版

        创建表使用函数SQLCreateTable(),这里定义一个窗口整型变量w_cID,供SQL函数使用。关于紫金桥实时数据库预定义的SQL函数的用法,请读者自行查看帮助,这里不再详述。

 

一旦数据表创建完毕,表模板就不再需要了。基于此原因,最开始的数据表是使用按钮创建的,创建完毕后,按钮就删除了,所以窗口中没有创建数据表的脚本。

 

5、建立绑定表。

数据表创建完毕后,接下来就是向表内插入数据了。要向关系数据库表内插入数据,需要使用紫金桥实时数据库的‘绑定表’,绑定表里的字段名设置要和表模版里的字段完全一致,否则插入数据时会失败。

另外,需要建立4个中间变量(图中变量名部分),分别对应数据表的4个字段,供绑定表使用,具体用法在后面脚本部分会详细介绍。

 

合格率绑定表

6、脚本。

由于紫金桥实时数据库6.5版软件里,窗口周期执行脚本的周期不能大于15分钟,所以为了实现需要的功能,定义以下整型窗口变量:w_cIDw_t1w_t2w_t3w_t4w_TBegin,具体使用在后面的脚本中说明。 

进入窗口:

进入窗口后,执行下面脚本,前三行是给w_t1w_t2w_t3赋值为次日零点的时间;第五行w_TBegin赋值为当日零点的时间,是报警统计组件执行统计的起始时间;第六行连接数据存储所使用的数据库,由于连接字符涉及到客户信息,所以这里去掉了,读者可以自己查看帮助中关于紫金桥软件内置SQL函数的用法,里面有关于连接数据库的详细说明。w_t4赋值为次日上午830分的时间,设备状态数据存储脚本使用,与合格率数据存储无关。

w_t1 = LongTime(StrLeft(StrTime($Curtime,0),10) + " 00:00:00") + 86400;

w_t2 = w_t1;

w_t3 = w_t1;

w_t4 = LongTime(StrLeft(StrTime($Curtime,0),10) + " 08:30:00") + 86400;

w_TBegin = LongTime(StrLeft(StrTime($Curtime,0),10) + " 00:00:00");

SQLConnect(w_cID,"此部分是数据库服务器连接字符串,不便公开");

 

周期执行:

首先,每天凌晨前5分钟,从关系数据库读取关键参数的报警限值到报表Fr1中。由于报警限值由工艺人员维护,可能根据工艺需要有修改,所以每天计算合格率之前要重新读取。脚本如下:

 

if $Curtime >= w_t1-300 && $Curtime < w_t1-240 then

        w_t1 = $Curtime + 86400;

       #Fr1.SqlSelectCmd("select 位号,指标级别,下限,上限 from TM_装置关键控制参数");

       Delay(1500);

       for i = 1 to #Fr1.RowCount()+1

                #本地.SetDataStr(#Fr1.Txt(1,i)+".EU",#Fr1.Txt(2,i));

                #本地.SetDataReal(#Fr1.Txt(1,i)+".EULO",#Fr1.Val(3,i));

                #本地.SetDataReal(#Fr1.Txt(1,i)+".EUHI",#Fr1.Val(4,i));

        # next

           #本地.RegUpdate();

endif

脚本第1行是判断本段脚本执行的时间,当系统时间处于零点前5分钟至前4分钟这段时间内,开始执行脚本;

2行是将变量w_t1的值增加一天的时间,以便下次执行的时间是在下一天的同一时间;

3行是报表Fr1从关系数据库的表中读取报警限值;

4行是延迟时间,以便报表Fr1能够完全读取表中的数据;

5~9行循环,将报表Fr1中的报警限值以及权重设置到对应的位号,第6行是设置权重,第7行是设置报警下限,第8行是设置报警上限;

10行,刷新第678行操作以后的点的信息。

 

读取报警限值后,接下来就是根据报警限值计算位号的合格率了。下面这段脚本是判断系统时间在零点前4分钟至3分钟之间,开始执行,同样把变量w_t2的值增加一天,即与w_t1相同,然后开始报警组件进行报警时间的统计,统计的时间是一天,即86400秒。

 

if $Curtime >= w_t2-240 && $Curtime < w_t2-180 then

        #w_t2 = w_t1;

        #Alarm1.Start(w_TBegin,86400,1);

endif

 

在报警统计组件完成统计后,接下来就需要将统计的数据提取出来,然后计算,再把计算结果存入数据库的表中了。

 

if $Curtime > w_t3-60 && $Curtime <= w_t3 then

        w_t3 = w_t1;

        for i = 0 to #Alarm1.GetTagCount()

        Bind_TagValue = 1 - (#Alarm1.GetCellHi(0,i) + #Alarm1.GetCellLow(0,i))/86400;

        Bind_TagName = #Alarm1.GetTag(i) + ".PV";

        Bind_StrTime = StrTime($Curtime,1);

        for j = 0 to #Fr1.RowCount()

        if #Alarm1.GetTag(i) == #Fr1.Txt(1,j+1) then

        Bind_TagLevel = #Fr1.Txt(2,j+1)

             endif

             next

             SQLInsert(w_cID,"XHQ_HGL","XHQ_BindHGL");

             next

endif

这部分脚本就是向数据库表内写入数据了。

1行仍然是判断时间,当时间达到零点前一分钟时,开始执行脚本,首先还是将时间变量w_t3增加一天,与w_t1相同;

3~13行循环,将报警组件中所有位号的值逐个进行计算,然后存入数据库的表中。

4行是把报警组件第i列的位号报警上限时间和报警下限时间求和,然后除以一天的时间,得到不合格率,再用1减去不合格率得到合格率的数值,赋给绑定表使用的变量;

5行是把报警组件第i列的位号赋给绑定表变量;

6行是把当前时间赋给绑定表变量;

7~11行,是在报表Fr1中查找当前第i列位号的权重,然后赋给绑定表变量;

12行,4个绑定表变量都已经赋值,此行使用紫金桥软件的SQL函数,将绑定表变量的值插入到关系数据库表中。

至此,完成报警组件第i列的一个循环,直至报警组件中所有位号的合格率统计值都插入数据表后,循环完成。

退出窗口:

这里只有一行脚本,就是当退出窗口时,断开与关系数据库的连接。

SQLDisconnect(w_cID);

整个脚本的关键,就是周期执行部分,这里使用了一个小技巧,由于紫金桥实时数据库6.5版,周期执行脚本的周期不能大于15分钟,所以这里使用一个整型变量,通过该变量的值与系统当前时间比较,只有符合条件才能执行脚本,否则不执行,这就保证了脚本只在每天指定的零点附近执行。

另外,为了保证每一部分的脚本能够完全执行完毕,并且不在时间上有交叉冲突,所以设置3个不同的时间变量,并且在不交叉的时间执行。而且通过这样的方法,不会影响其他需要频繁执行的周期脚本正常运行。

  

总结:

本例中使用了报表关系数据源点与自由报表相结合,读取关系数据库表中的数据,这样的好处是操作简单,不需要写过多脚本,但是无法向数据库表中写入数据。

又使用了紫金桥实时数据库软件预定义的SQL函数,向关系数据库中写入数据。SQL函数的优点是功能全面,几乎能够完成对关系数据库表的所有操作,包括查询、插入、删除、建表、删表等等;缺点就是操作相对自由报表和报表关系数据源点的结合要繁琐一些,需要建立表模版、绑定表,还要手动写一些脚本等。


1楼 0 0 回复