主题
虚拟点
在工控应用场景下,大部分数据点都是物理点位,包括开关量、模拟量等。软件提供了虚拟点位的支持,允许用户通过编写计算表达式,生成虚拟变量。 使用虚拟点位需要配置点位通讯参数中的两个字段:
- 将“虚拟点位”设置为“启用”状态。
- 在点位地址中输入计算表达式。
计算表达式示例:
- 基本表达式:
10 > 0 - 带变量参数:
foo > 0 - 带算术运算符:
(v1 * v2 / 100) >= 90 - 字符串判断:
v1 == "service is ok" - 数值运算表达式:
(mem_used / total_mem) * 100
测点变量
计算表达式的上下文中,以变量形式注入了同设备下的所有测点的值,变量名为对应测点的【点位标识】,所以点位标识的命名请确保使用英文字母、数字、下划线的组合。
示例:
假设同一设备下有 3 个温度测点,点位标识分别为:T1, T2, T3。
如果要计算这 3 个温度测点的平均值,那么就可以定义一个虚拟点 T_AVG,表达式内容为:(T1 + T2 + T3) / 3。
如果测点标识采用数字开头进行命名,比如 1T,在使用表达式时不能直接使用变量名,可以使用内置函数 GetValue("T1")。
NOTE
GetValue还可以用于引用其它设备下的测点值,比如设备标识为 mydevice1 下的 T1,请使用 GetValue('mydevice1.T1')。
常量
| 名称 | 说明 |
|---|---|
| 数值型 | 类型为 64位浮点型:12345.678 |
| 字符串 | 用双引号表示: "foobar" |
| 布尔型 | true 或 false |
| 日期 | Date(x) 支持 RFC3339, ISO8601, unix |
算数运算符
假定 A 值为 10,B 值为 20。
| 运算符 | 描述 | 实例 |
|---|---|---|
| + | 相加 | A + B 输出结果 30 |
| - | 相减 | A - B 输出结果 -10 |
| * | 相乘 | A * B 输出结果 200 |
| / | 相除 | B / A 输出结果 2 |
| % | 求余 | B % A 输出结果 0 |
关系运算符
表达式成立返回 true 否则返回 false。假定 A 值为 10,B 值为 20。
| 运算符 | 描述 | 实例 |
|---|---|---|
== | 检查两个值是否相等 | (A == B) 为 false |
!= | 检查两个值是否不相等 | (A != B) 为 true |
> | 检查左边值是否大于右边值 | (A > B) 为 false |
< | 检查左边值是否小于右边值 | (A < B) 为 true |
>= | 检查左边值是否大于等于右边值 | (A >= B) 为 false |
<= | 检查左边值是否小于等于右边值。 | (A <= B) 为 true |
逻辑运算符
假定 A 值为 true,B 值为 false。
| 运算符 | 描述 | 实例 |
|---|---|---|
&& | 逻辑与。 如果两边的操作数都是 true,则输出 true,否则为 false。 | (A && B) 为 false |
| `||` | 逻辑或。 如果两边的操作数有一个 true,则输出 true,否则为 false。 | (A || B) 为 true |
! | 逻辑非(对原值进行取反)。 | !(A && B) 为 true |
位运算符
位运算符对整数在内存中的二进制位进行操作。
假定 A 为60,B 为13:
| 运算符 | 描述 | 实例 |
|---|---|---|
& | 按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。 | (A & B) 结果为 12, 二进制为 0000 1100 |
| | 按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或 | (A | B) 结果为 61, 二进制为 0011 1101 |
^ | 按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 | (A ^ B) 结果为 49, 二进制为 0011 0001 |
<< | 左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | A << 2 结果为 240 ,二进制为 1111 0000 |
>> | 右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数。 | A >> 2 结果为 15 ,二进制为 0000 1111 |
三元操作符
格式为:? :,如 (v1 > 100) ? 1 : 0
优先级顺序
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低:
| 优先级 | 运算符 |
|---|---|
| 5 | * / % << >> & &^ |
| 4 | + - | ^ |
| 3 | == != < <= > >= |
| 2 | && |
| 1 | ` |
可以通过使用括号来临时提升某个表达式的整体运算优先级。
内置函数
| 名称 | 说明 |
|---|---|
Math.ABS(number) | 取绝对值 |
Math.MAX(number, number) | 取两个值中的最大值 |
Math.MIN(number, number) | 取两个值中的最小值 |
GetValue(string) | 获取测点值,入参为测点全局标识: 设备标识.测点标识 或 测点标识(同设备下的测点) |
Integration(string) | 对某个测点值按时间计算积分,时间为虚拟点的扫描周期,单位为秒。计算公式:t*(v2+v1)/2,其中 t 为扫描周期(秒),v1 和 v2 分别为本期和上期扫描到的测点值。 |
Derivative(string) | 对某个测点值按时间计算导数,时间区间取决于虚拟点的扫描周期,单位为秒。计算公式:(v2-v1)/t,其中 t 为扫描周期(秒),v1 和 v2 分别为本期和上期扫描到的测点值。 |
示例:
- 某温度点的标识为 T,如果希望每分钟计算 1 次该测点的导数。可以新建一个虚拟点,扫描周期设置为 60 秒,表达式为 Derivative("T") * 60。
- 某温度测点标识为 T,如果希望每分钟计算 10 次该测点的导数。可以新建一个虚拟点,扫描周期设置为 6 秒,表达式为 Derivative("T") * 6。
- 某瞬时流量的测点标识为 L,单位为 m3/s,如果希望每分钟计算 1 次累计流量。可以新建一个虚拟点,扫描周期设置为 60 秒,表达式为 `Integration("T") 。