iHyperDB表达式计算功能介绍
●表达式计算模块为用户提供了一种新的途径对普通Tag点进行计算。用户可以通过客户端配置一个计算点,其表达式关联一个或者多个普通的Tag点,计算服务获取到用户配置的计算点自动计算出表达式的结果,然后保存成计算点的记录,存储到Kernel中。
●系统管理工具提供对计算机点的配置管理功能,包括计算点的创建、删除和修改。计算点的数据类型为int32或者float64两种。
计算点除了配置“基本”TAB页,“存储”TAB页,“权限”TAB页,“系统”TAB页外,还要配置“计算”TAB页。
在创建计算点时,需配置下列信息:
✓计算模式:
轮询--按一定的周期处理计算;
通知--关联的监测点的snapshot发生改变时触发计算。如下图:
✓周期:
计算周期,根据此周期设置定时器对表达式进行计算,计算模式为通知的时候周期不可配置。周期必须小于被过滤点的采集周期
✓变量表达式:
这项是计算的重点,计算服务根据表达式做计算。变量以'标识,如'Tag1'+'Tag2',目前支持四则混合运算以及关系运算符、逻辑运算符;
✓计算历史:
用户勾选起始时间,表示对计算点的历史数据进行计算;用户可选择是否配置历史数据结束时间。若配置了结束时间,则计算点添加成功后开始计算历史数据,计算时指定区间内有所有历史数据计算完成后,就不再计算。若未配置结束时间,则计算点添加成功后开始计算,计算至最后一条历史记录后,将该点转为实时计算。注意通知模式不支持计算历史。
表达式计算服务部署在服务端,计算服务根据计算点配置,在计算点的计算周期到达时候,自动触发计算点的表达式计算,并将对应的计算点记录写入实时数据库。
▪基本运算
计算服务支持关系运算符,逻辑运算符和位运算符,配置规则如下:
✓在配置的时候对表达式涉及的普通点类型不做校验,但是在计算的时候,不支持string和blob类型的普通点的计算。
✓运算符的优先级(从高到低)如下:
优先级 |
运算符 |
含义 |
|
|
12 |
! |
逻辑非运算 |
|
|
11 |
~ |
按位取反运算 |
|
|
10 |
/ |
除 |
|
|
|
* |
乘 |
|
|
9 |
>> |
位运算右移 |
|
|
|
<< |
位运算左移 |
|
|
8 |
> |
大于 |
|
|
|
>= |
大于等于 |
|
|
|
< |
小于 |
|
|
|
<= |
小于等于 |
|
|
7 |
== |
等于 |
|
|
|
<> |
不等于 |
|
|
6 |
& |
按位与运算 |
|
|
5 |
^ |
按位异或 |
|
|
4 |
| |
按位或 |
|
|
3 |
&& |
逻辑与 |
|
|
2 |
|| |
逻辑或 |
|
|
1 |
?: |
条件运算符 |
|
|
✓位运算只能用于整型操作数(int8,int16和int32),如果变量的实时值不是整型则会强制类型转换为整型 int32参与计算。另外,对于“<<”、“>>”操作符,表达式'Tag1'>>2和2<<‘Tag1’的意义和计算结果都不相同,配置的时候请注意。
✓关系运算符的运算结果是布尔型的,满足为1,不满足为0。结果可参与逻辑运算,实际上不参与四则混合运算,如果你配置('Tag1'>=100)+1实际上可能没有意义,但是仍可以得到1或者2这个结果。
✓条件运算符?:可以嵌套,不过要用()标明运算顺序,例如:
✓'Tag1'>100?'Tag1'-50:'Tag1'+50
✓'Tag1'>100?('Tag1'<50?'Tag1'+50:'Tag1'-50):'Tag1'
✓正负号要用()标明运算顺序,例如:'int8'*(-1),如没有()则计算结果不正确.
✓IF条件语句表达式,如IF (‘Tag1’>50) THEN (1) ELSE(0);含义如果Tag>50,则该计算点值为1,否则为0;
其中不能缺少else字段, 关键字段后表达式都要括号。
1、大于>、大于等于>=、小于<、小于等于<= 运算符不支持连续操作,如‘TAG1’> 'TAG2'>3,若需要上述处理,可以用(‘TAG1’>'TAG2')&&(‘TAG2’> 3); 2、参与计算的点,必须是普通点; 3、计算点的时间戳取表达式中关联的普通点的最新时间戳,表达式关联的普通点取最新的snapshot; 4、如果表达式中的普通点取值正常,计算失败(比如分母为0),则计算点不保存记录; 5、表达式关联的普通点,如果是停机记录也会运算,计算点的数据质量为BAD; 6、计算点表达式配置:如果表达式以西文单引号'开始,请将整个表达式圆括号()包围起来,这样使用Excel配置表达式时,Excel不会将西文单引号'自动过滤掉。例如将'tag1'+1 配置为('tag'+1). 7、计算表达式支持计算点本身。 |
点击计算点配置页面的Func按钮弹出内置函数选择对话框,如下图:
✓极大值过滤
支持极大值过滤:根据指定的“阀值”过滤掉“极大值”,将未过滤的点保存。
极大值过滤的函数名称:FilExtream('pt_tag', cal_tag, timeInterval, fValue)。
函数说明:可以输入四个参数
1):第一个参数:'pt_tag'是第一个参数,为被过滤的点名(必须带单引号,点的类型不可以为string或blob或digital类型);
2)、第二个参数:cal_tag,为保存过滤结果的点名(即计算点自身点名, 不带单引号);
3)、第三个参数:timeInterval,为允许过滤的最大间隔(单位秒);
4)、第四个参数: fValue,为过滤的阈值。
举例:比如FilExtream('pt_tag', cal_tag, 10,40),代表从起始时间开始,pt_tag的第二个点与第一个点比较,如果两点连线的斜率大于40,则过滤第二个点,如果小于40,则将第二个点保留;将第二个数与第三个点比较,如果两点连线的斜率大于40,则抛弃第三个点,如果小于40,则将第三个点保留。以此类推。 ( 如果某个点之前10秒无点可比较,则将此点保存并作为第一个点供其后点比较。)
1、斜率计算规则(pt_tag.value - cal_tag.value)/(pt_tag.time - cal_tag.time) > fvalue; 2、假设被过滤的点的实际间隔为60秒,则过滤的最大间隔,即第三个参数,要大于60秒。否则,根据过滤原则,过滤间隔前无可比较值,则存储该点,导致无法过滤极大值; 3、假设被过滤的点的实际间隔为60秒,则配置计算属性时,周期时间要小于60秒;否则,计算点过滤时,会跳过某些点,导致无法完全过滤极大值;(以上2和3点的时间间隔无关联); 4、过滤的阈值一般为比较小的正数;如果阈值是1,则等于是过滤掉斜率角度大于45度以外的点;如果阈值是2,则等于是过滤掉斜率角度大于45度以外的点;因此,如果是较大的正数,或者是负数,则起不到过滤极大值的作用; 5、极大值过滤表达式不推荐和其他表达式如+、-、*、/等使用,适合单独使用运算; 6、遇到数据质量为bad点,不论该点是否超过极大值,均保存,且不参与后续比较。如第二个点为bad,则cal_tag的第三个点和第一个点进行比较,和bad点无关; |
示例:
实时数据库中新建普通点pt_tag,
新建计算点ca_tag,计算表达式配置为filextream(‘pt_tag’,ca_tag,60,1);
❖pt_tag导入记录,
1)pt_record-> time: 2014-06-20 10:00:00, value:0,quality:good
2)由于是首条记录,在time之前pt_tag没有记录值,所以ca_tag直接保存该条记录,
3)ca_tag记录:ca_record->2014-06-20 10:00:00, value:0,quality:good
❖pt_tag继续导入记录,
1)pt_record->2014-06-20 10:00:10, value:5,quality:good
2)该条记录时间戳和ca_tag上一条good记录时间戳相差10s < 60s,故需计算,(5-0)/(10-0) = 0.5<1,所以该条记录不需要过滤,保存。
3)ca_tag记录:ca_record->2014-06-20 10:00:10, value:5,quality:good
❖pt_tag导入记录,
1)pt_record->2014-06-20 10:00:20, value:16,quality:good
2)该条记录时间戳和ca_tag上一条good记录时间戳相差10s < 60s,故需计算,(16-5)/(20-10)=1.1>1,超过阈值1,故此条记录过滤,不保存为计算点记录
❖pt_tag导入记录,
1)pt_record->2014-06-20 10:00:30, value:15,quality:good
2)该条记录时间戳和ca_tag上一条good记录时间戳相差10s < 60s,故需计算,(15-5)/(30-10)=0.5<1,超过阈值1,所以该条记录不需要过滤,保存
3)ca_tag记录:ca_record->2014-06-20 10:00:30, value:15,quality:good
❖pt_tag导入记录,
1)pt_record->2014-06-20 10:01:40, value:110,quality:good
2)该条记录时间戳和ca_tag上一条good记录时间戳相差70s > 60s,超过最长时间间隔,故不需要经过计算,直接保存
3)ca_tag记录:ca_record->2014-06-20 10:00:30, value:110,quality:good
✓TagYear(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的年份。
参数说明:点名
✓TagMonth(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的月份(1-12)。
参数说明:点名
✓TagDay(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的日(1-31)。
参数说明:点名
✓TagHour(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的小时(0-23)。
参数说明:点名
✓TagMinute(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的分钟(0-59)。
参数说明:点名
✓TagSecond(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的秒(0-59)。
参数说明:点名
✓TagWeekday(‘pt_tag’);
函数说明:获取点pt_tag的快照时间的星期(1-7)。
参数说明:点名
✓TagYearday(‘pt_tag’);
函数说明:获取点pt_tag的快照时间在今年是第几天(1-366)。
参数说明:点名
✓TagDaysec(‘pt_tag’);
函数说明:获取点pt_tag的快照时间是今天的第几秒(0-86399)。
参数说明:点名
✓TagUnixsec(‘pt_tag’);
函数说明:从1970年1月1日零点到现在的秒数。
参数说明:点名
✓PrevVal(‘pt_tag’);
函数说明:获取前一个点值。
例如:配置if((PrevVal('Tag1')==0) && ('Tag1'==1)) then(1) else(NoOutput())表示计算点监控到源点的值从0变到1时保存值1到,否则不计算。
参数说明:点名
✓NoOutput();
函数说明:不将计算结果进行保存。
参数说明:无
例如:配置if('Tag1'>100) then('Tag1') else(NoOutput())
表示过滤掉小于等于100的源值
✓BadVal(‘pt_tag’);
函数说明:检查数据质量是否为bad,bad返回true,其它返回false。
参数说明:点名
例如:配置if(BadVal('Tag1')) then(NoOutput()) else('tag1')
过滤掉源点数据质量为bad的点
✓PreUnixsec(‘pt_tag’);
函数说明:前一条记录的从1970年1月1日零点到现在的秒数。
参数说明:点名
✓PreMs(‘pt_tag’);
函数说明:前一条记录的毫秒值,毫秒值在0-999之间。
参数说明:点名
✓PreBadVal(‘pt_tag’);
函数说明:前一条记录的数据质量,数据质量为Good返回0,其它返回1。
参数说明:点名
✓NoneRecord('pt_tag');
函数说明:函数说明:检查数据点是否存在记录,不存在记录则函数返回true,存在记录返回false。
参数说明:点名
例如:If (NoneRecord('tag1’))then(1) else('tag1’)
如果tag1没有记录值输出1,如果有记录值输出tag1.
删除内置函数时,只校验SPC报警点,其余类型不校验。 |