紫金桥软件自带了过程数据库,可以高效的保存相关数据点的历史记录,同时提供了丰富的方法读取所需的历史记录。笔者使用紫金桥做了多个工程,仅就个人经验进行简单小结,这里和大家分享,还望能起到抛砖引玉的作用,如有不对之处,还望指正。
关于保存历史记录
通过紫金桥组态软件自身的过程数据库,可以通过两种方式自动保存数据点的历史记录,定时保存和变化率保存,定时保存适合保存变化不是很快,或者比较有规律的数据点,变化率保存的应用范围相对更广,适合变化较快或者较慢的情形,这里要注意两点内容:
-
对于定时保存的历史记录一般不做压缩的,所以不建议对于较多的数据库点设置为保存间隔较短的定时保存,否则历史记录的文件体积会增加相对较快;
-
对于变化率保存的数据,系统会自动压缩保存,要注意的是其变化率是相对于该点的量程而言的,而不是相对于上次保存的历史值。数据点的量程可以在“点组态”基本参数中修改;
个人觉得过程数据库很适合保存现场连续的采集值,对于一些字符型的数据,可能还需要借助关系数据库来保留历史值了。而关系数据库在保存连续数值方面也远不如过程数据库方便。关于紫金桥对关系数据库的各种操作,笔者将在其它文档中进行说明,这里不再赘述。
历史数据的读取
紫金桥软件提供了多种方式读取历史数据,这里仅就一些常用的方法进行说明。一般有三种方式读取历史记录,分别是:历史曲线、读取单点历史、读取批量历史。在说明各种方式之前先要解释下“坏值”的概念,数据点只有在系统运行时才能保存历史记录,对于系统没有运行时的历史值,如果该时刻早于当前时刻,紫金桥软件通常会赋一个坏值,-9999。而对于未到时间的历史值可以在“系统参数”进行设置,如图所示:
下面简述下读取历史记录的三种操作:
1 通过历史曲线
通过历史曲线或者趋势分析曲线可以直接查询相关点的历史值,这种方法的优点在于数据很直观,便捷、曲线可以任意放大。
历史曲线:
趋势分析:
历史曲线和趋势分析曲线的不同在于,历史曲线可以通过“打散单元”的操作将该组件分解,自行根据需要重新组合;而趋势分析组件功能更强,提供了历史曲线没有的统计数据、全屏显示等功能,但是不支持分解操作,不能自行组合。
2 读取单点历史记录
单独采集某点某时刻的历史值或某段时间的统计值一般通过脚本函数实现:
-
读取某刻历史值一般使用三种函数:GetHisData(Var,Year,Month,Day,Hour,Minute,Second,MilliSec);
GetHisData2(Var,StartTime, MilliSec);
GetHisDataEx(DataSource, VarName ,StartTime,MilliSecond);
GetHisData和GetHisData2前者适合读取具体时刻的历史值,后者通过一个时间值来获取历史记录,该值是一个整数,表示相对于1970年1月1日08:00时过去的秒数,这个秒数在紫金桥软件中非常常用。实际工程中,这个秒数可以通过函数LongTime ("2001/01/01 14:50:48")得到,该函数可以自动得到某时刻过去的秒数。秒数也可以通过一些组件得到,比如起始时间组件,如图所示:
图中有一个起始时间组件,其下是该组件的time属性所对应的相对于1970/1/1/08:00:00 过去的秒数。比如该组件被命名为EndTime,在脚本中通过#EndTime.time即可得到相应的秒数。
-
读取某段时间内的统计值可以通过函数GetStatisDataEx(DataSource,VarName, StartTime,TimeSpan, Flag,Time)或GetStatisData(Var, Year, Month, Day, Hour, TimeSpan, Flag,Time)得到一段时间内的最大值、最小值或者平均值。
val = GetStatisDataEx("","FQ101.PV", LongTime("2007/09/04 14:30:00"), 2,0,strTime) 示例中Val变量可以得到FQ101.pv值在2007年9月4日14点30分起2个小时内的平均值。这里要注意的是,GetStatisData 和GetStatisDataEx函数会自动过滤掉坏值。在使用统计函数时,要确保对应的点在组态时选择上统计设置,如图所示:
此外还要注意的是,由于紫金桥系统是每小时自动统计下历史记录,对于刚保存的历史记录,比如1小时内的历史值,通过统计函数可能无法得到最新的统计值。如果需要得到即时的统计值,需要借助紫金桥软件提供的SPC历史组件进行统计。关于该组件的一些操作可以参看紫金桥软件相关帮助文档。
3 读取批量历史
读取批量历史通常以报表的形式显示出来。对于历史报表,依据不同的标准有不同的分法,按照行数区分可以分为固定行列和不固定行数,按显示的类型可以分为统计和非统计历史报表。所谓统计报表通常是对一些累加值的点进行统计,比如最大值、最小值、或者平均值等,非统计报表就是直接查询某时刻的历史值。不同情况下具体实现的方法也各不同,这里仅就笔者熟悉的方法进行简述。
行数固定的非统计历史报表
对于需要获取某段时间内,固定时间间隔的历史记录,通常其行数是固定的,比如需要对一天内的整点数值采样,其行数是24,时间间隔一小时。这种情况下,使用自由报表的“取批量历史”功能最为简单。具体操作方式简述如下:
首先选中自由报表中需要显示历史记录的一列,然后点击自由报表工具栏中右侧的公式选择按钮,如图所示:
点击后选择“取批量历史”,如图所示:
系统弹出对话框:
在“数据库变量”中填写所关联的数据点,比如“A1.pv”,根据实际情况设定“采集个数”和“时间间隔”,“采集个数”不能填写为变量。这里的“时间表达式”是指批量历史中首个采集点的时间,可以是一个整形变量,其值是前文中提到的1970年1月1日08:00时过去的秒数。
优点:通过取批量历史的功能,可以轻松的获取某点采集个数固定,时间间隔固定的历史记录。
缺点:无法实现采集时间不固定、采集历史记录个数不固定的要求,无法采集统计值。
小技巧:通常显示历史记录的时候,往往需要在另一行显示该记录相对应的时间,可以选择一列,将该列的输入输出设置为“日期和时间”,然后将该列关联和历史值对应的秒数即可。
行数不固定的非统计报表
有时需要用户自行设置历史记录查询的开始时间和结束时间,查询的历史记录的间隔时间,这时往往需要借助历史数据对象来获取记录。
在紫金桥的图库中“历史数据”选择“历史数据对象”,如图所示:
将其拖拽置窗口,系统自动增加一历史数据对象,如图所示:
双击该对象,可以在属性对话框中进行参数设置,如图所示:
该组件通常运行时是隐藏的。可以在属性设置对话框中增加所需查询的历史点(可以同时查询多个)。通过点击“事件脚本”,可以在此编写所需的脚本语句,如图所示:
通常是通过按钮等事件调用历史数据对象的Start(BeginTime, Cycle, Count)函数,通过该函数可以设置查询的开始时间,查询的时间周期和查询的历史个数,并进行查询。当查询结束后,会执行“检索完成时”脚本。一般在“检索完成时”的脚本中通过一个循环语句,把查询到的结果更新到自由报表中。例如脚本:
num=#his.GetColCount();//得到查询的行数
for k=1to num+1step1
#report.settxt(1,k+1,#his.GetTimeText(k-1,0));//得到时间
#report.settxt(2,k+1,#his.GetCellText(0,k-1));//得到变量1的历史值
#report.settxt(3,k+1,#his.GetCellText(1,k-1));//得到变量2的历史值
Next
该脚本首先获得历史数据对象查询的数据行数,然后逐行赋值给自由报表中指定的单元格。关于该组件的更详细操作可以参看紫金桥软件的说明书。
优点:可以方便的采集行数固定或不固定的历史值。
统计报表
对于有些报表,需要统计一些历史值,比如一段时间的最大值、最小值、平均值或者某段时间内,历史值的最大值和最小值的差值(比如产量)。这类报表可以通过SPC控件或者历史摘要控件进行读取统计值,然后再写入自由报表中,也可以直接使用统计函数获取统计值。关于SPC控件和历史摘要控件的操作方法和上文中提到了历史数据对象比较类似,具体内容和相关函数可以参看紫金桥软件说明书。其中SPC控件可以从任意时段的历史数据中进行抽样统计,进行SPC统计的点是否选择了“是否统计”都不影响SPC分析;而历史摘要控件选择的是该点的统计值,进行历史摘要的点必须选择“统计”,而统计往往是以小时为单位的,所以相对于SPC控件,摘要控件统计的结果更为准确,但是时间跨度需要大于一小时。
这里要说明的是,对于一些累加的值而言,比如产量等,有时需要得到一段时间内的差值,有些用户往往会用结束时刻的历史值减去开始时刻的历史值,这种做法是有隐患的,因为开始时刻或者结束时刻系统可能处于未运行状态,这时,历史值会是坏值-9999。所以建议的做法是选取这段时间内的最大统计值减去这段时间内的最小统计值(系统会自动过滤坏值),不过获取统计值的速度会比获取历史值的速度稍慢一点,如果该段时间跨度很大,可以适当缩小统计值的时间范围。
其他历史报表
有时可能需要统计一些离散的历史值,比如在检测行业,每次测量的时间间隔可能不固定,测量次数可能也不确定,这时想查询历史检测记录,使用前面提到的方法都难以实现。这里推荐两种做法:
-
设置一个标记点,该标记点使用变化率保存历史记录,每测量结束后,都改变一次标记点的值,其他测量值同样保持历史记录,查询时使用“取全部历史数据对象”组件(在图库中“历史数据”中调用),如图所示:
通过该组件可以查询这个标记点指定范围内的所有历史记录,同时可以查询到该时刻时其他测量值的历史值。比如,工程中有A1和A2两个位号,A1是标记点,现在希望查询A1的在当天的所有历史数据。比如查到的结果是12:23:18.102时刻有一个历史数据,18:43:25.358时刻有一个历史数据。这时希望同时查询A2在12:23:18.102时刻和18:43:25.358时刻的历史数据。进入“取全部历史数据”对象的报表设置界面:
可以看到,报表的前3列分别是时间、毫秒和查询的位号的数据,可以在后面增加一列,比如A2.PV,见上图。并在下面输入如下的脚本=GetHisData2(A2.PV, Val(1,$R), Val(2,$R)) 。这段脚本的意义是取A2.PV的历史数据,其中时间采用左侧第一列的时间,毫秒数采用左侧第二列的时间。当组件查询到A1.PV的历史数据的时候,会自动地增加报表的行数来存放相应的数据。同时也会自动地复制上面输入的脚本,这样后面的列就能显示A2.PV的相应时刻的历史数据了。
优点:无需借助关系数据库,即可查询离散的无规律变化的历史记录;
缺点:受过程数据库自身的局限,无法保存字符型历史记录。
-
每次测量结束后,将测量数据保存到关系数据库中,然后通过自由报表查询关系数据库中的历史记录。
优点:可以方便的保存字符型或非字符型的离散历史记录;
缺点:需要关系库的支持;
本文简述了读取紫金桥软件历史数据库的三种方式:曲线、函数、报表,并详细介绍了各种情况下使用报表读取历史数据的不同操作方法,当然具体操作中,还有更多其他的方法可以选择。希望以上介绍能对各位操作紫金桥软件有所帮助,也希望起到抛砖引玉的作用,欢迎提出更好操作方法,彼此讨论提高。