在工业控制中,常常要从一些数据的历史趋势中分析问题和发现问题。紫金桥实时数据库支持历史数据的快速保存和检索,可以按照一定的条件把数据保存到历史库中,用户需要时可随时访问。
历史数据一般是点的某个参数在过去某一时刻的瞬时值,是与时间有关的数据,每一个历史数据记录上都有一个时间戳,记录历史数据的采样时间。位号是否保存历史数据,历史数据的保存条件都由用户进行数据组态时决定。实时数据库按照用户指定的采样条件在库中进行采样,如果采样的条件满足,就将采样数据加上时间戳,记入历史库中。
历史数据库是磁盘文件,为了防止频繁的写磁盘,紫金桥实时数据库在内存中开辟了历史数据缓冲区。历史数据从实时数据库中采集以后,首先放在内存缓冲区中,当存盘时间到达或缓冲区已满时一次性的写入磁盘历史库文件。用户访问历史数据时,系统首先检查历史数据缓冲区中是否有用户需要的历史数据,如果没有然后在检查历史数据库文件中是否有用户需要的历史数据。历史数据缓冲区的设立大大加快了历史数据的存取速度。
紫金桥历史数据库具有如下特点:
u 紫金桥实时数据库能够将任何点的任何参数存盘。
u 无论数据来源于现场设备、人工录入数据、还是计算结果都能存入历史数据库。
u 具有先进的数据压缩算法,能够充分利用有限的盘空间存储长期的历史数据
u 具有历史插值功能。
对于某些特定的应用,需要修改历史数据,紫金桥实时数据库没有提供相关修改历史数据的方法,但通过上述的历史插值功能,可以完成历史数据修改的目的。下面通过一个简单的示例,介绍下历史数据的修改。
在工程中新建一个窗口,添加如下组件:
为了能用脚本调用各组件的功能,将各组件命名为:
组件 |
名称 |
取历史组件 |
His |
左侧下拉框 |
tagSel |
起始时间 |
BegTime |
时间范围 |
TimeLen |
左侧报表 |
list |
右侧下拉框 |
tagSel2 |
右侧报表 |
newList |
设计思路:
1.查询:通过下拉框选择要修改的数据库点,点击查询按钮时,用起始时间和结束时间组件的设置,通过取取历史组件查询该段时间范围内的历史数据,然后将数据显示在报表中。点击导出到Excel按钮,将报表中的数据(包括时间和数值)导出至Excel中。
2.修改:利用Excel打开保存的文件,修改数据。
3.插值:选择对应的数据库点,点击选择Excel文件按钮,加载Excel修改后的文件,将数据显示在报表中,点击插入历史数据库按钮,完成历史数据的插入。
实现方法:
1.将要修改的点在添加至下拉框中。
2.在查询按钮中添加自定义动作,如下:
string strCurTag = #tagSel.GetCurItemText();
strCurTag = StrTrimLeft(strCurTag);
strCurTag = StrTrimRight(strCurTag);
if StrInStr(StrLower(strCurTag),".pv",0) < 0 then
strCurTag = strCurTag+".pv";
endif
#his.FindHisEx(strCurTag,#BegTime.Time,#TimeLen.Time); //利用取历史组件的FindHisEx函数,查询某一数据库点在指定时间范围内的历史数据。
3.将取历史组件中的数据导出至报表中,设置取历史组件的数据刷新动作为:
//调整报表的显示行数,如果不足20行,则显示20行,大于则显示实际的行数
#list.DeleteRow(21,#list.RowCount());
int nListCnt = #list.RowCount();
int nDataCnt = #his.GetDataCount();
#list.ClearRowData(1,nListCnt);
if nDataCnt > nListCnt then
#list.AddRow(nDataCnt-nlistCnt);
Endif
//通过for循环将数据添加至报表中
int i=0;
int nTime = 0;
int nMS = 0;
real rData = 0;
for i=1 to nDataCnt+1
nTime = #his.GetDataTime(i);
#list.SetVal(1,i,nTime);
nMs = #his.GetDataMS(i);
#list.SetVal(2,i,nMs);
rData = #his.GetData(i);
#list.SetVal(3,i,rData);
Next
4.导出Excel按钮脚本,如下:
#list.SaveAsEx("",0);
利用报表的SaveAsEx函数实现报表数据导出Exce文件功能。
5.选择Exce按钮脚本,如下:
#newList.LoadAsEx("",0);
6.插入历史数据库脚本,如下:
int nCnt = #hisList.RowCount();
int i=0;
string strCurTag = #tagSel2.GetCurItemText();
strCurTag = StrTrimLeft(strCurTag);
strCurTag = StrTrimRight(strCurTag);
if StrInStr(StrLower(strCurTag),".pv",0) < 0 then
strCurTag = strCurTag+".pv";
endif
for i=1 to nCnt+1
InsertHisDataEx("",strCurTag,#hisList.Val(3,i),#hisList.Val(1,i),#hisList.Val(2,i));
Next
利用InsertHisDataEx函数,实现历史数据的插值,如果该时间戳已经存在,数据库自动替换该值。
总结:利用该功能可以方便的完成历史数据的修改,紫金桥实时数据库对历史数据的操作提供了灵活的操作手段。历史数据保存对数据完整性和数据的压缩比上有较好的兼顾平衡,数据保存结构先进合理,使得在检索有较高的效率,系统提供多种数据查询手段,包括单点数据查询,批量数据查询,指定时间格式查询、任意时间段数据查询等都有对应的组件。历史数据的处理是实时数据库的重要性能指标,紫金桥实时数据库有着独到的优势。