预警表达式教程
基础语法
字面值
| 数据类型 | 字面值 |
|---|---|
| Comment | /* */ or // |
| Boolean | true、false |
| Integer | 42 、0x2A 、0o52、0b101010 |
| Float | 0.5、.5 |
| String | "foo"、'bar' |
| Array | [1, 2, 3] |
| Map | {a: 1, b: 2, c: 3} |
| Nil | nil |
操作符
| 操作符 | 描述 |
|---|---|
| Arithmetic | +, -, *, /, % (modulus), ^ or **(exponent), |
| Comparison | ==, !=, <, >, <=, >= |
| Logical | not or !, and or &&, or or || |
| Conditional | ?: (ternary), ?? (nil coalescing) |
| Membership | [], ., ?., in |
| String | + (concatenation), contains, startsWith, endsWith |
| Regex | matches |
| Range | .. |
| Slice | [:] |
| Pipe | | |
上面介绍了基础语法和标识,更多资源可以查看:https://expr-lang.org/docs/language-definition 。Expr 表达式语法和 C、Go、Lua、Python,JavaScript 高度相似,可以举一反三。
数据示例
以下是一个气象站数据的 JSON 示例。这个示例包含了气象站的基本信息、位置、以及一系列的气象观测数据:
JSON
{
"observation": {
"timestamp": "2024-12-06T15:30:00Z",
"weather": {
"temperature": {
"value": 5.0,
"unit": "C"
},
"humidity": {
"value": 85,
"unit": "%"
},
"pressure": {
"value": 1012.3,
"unit": "hPa"
},
"wind": {
"speed": {
"value": 12.0,
"unit": "km/h"
},
"direction": {
"value": 270,
"unit": "degrees"
}
}
}
}
}在这个 JSON 示例中:
observation对象包含了气象观测数据,包括观测的时间戳。weather对象包含了具体的气象数据,如温度、湿度、气压、风速、风向、降水量、云量和能见度。- 每个气象数据项都包含了
value和unit字段,分别表示观测值和单位。
这个 JSON 结构是通用的,可以根据实际需要添加或删除字段。
示例1:气象站数据处理
温度大于 30:
Lua
observation.weather.temperature.value > 30
气压在某个阈值:
Lua
observation.weather.pressure.value > 1001 && observation.pressure.value < 1005 
温度*湿度在某个阈值区间:
Lua
observation.weather.temperature.value * observation.weather.humidity.value > 30
示例2:温湿度传感器数据处理
下面是 Modbus 采集上来的数据,要求:当值 >100 的时候预警:
Lua
{
"tag": "temp2",
"alias": "传感器1-温度",
"slaverId": 2,
"lastFetchTime": 1733836405282,
"value": "222.2000"
}预警规则:
Lua
float(value) > 100
这里涉及到一个类型转换 float(value),“222.2000” 是个字符串,使用类型转换即可直接转换为对应的类型。
示例3:高级操作
有两个温湿度传感器,点位定义如下:

现在采集两个 Modbus 传感器的数据,采集到的数据如下:
Lua
{
"data": [
{
"tag": "humi1",
"alias": "传感器1-湿度",
"slaverId": 1,
"lastFetchTime": 1733891948921,
"value": "1111.1000"
},
{
"tag": "temp1",
"alias": "传感器1-温度",
"slaverId": 1,
"lastFetchTime": 1733891949048,
"value": "1111.1000"
},
{
"tag": "humi2",
"alias": "传感器2-湿度",
"slaverId": 2,
"lastFetchTime": 1733891949176,
"value": "1111.1000"
},
{
"tag": "temp2",
"alias": "传感器2-温度",
"slaverId": 2,
"lastFetchTime": 1733891949303,
"value": "1000.0000"
}
]
}规则:
- 传感器1-温度是否高于 1000 摄氏度?
Lua
any(data, {.tag == "temp1" && float(.value) >= 1000}) - 传感器2-湿度是否高于 80?
Lua
any(data, {.tag == "humi2" && float(.value) >= 80}) - 传感器 1、传感器 2 的温度是否都高于 1000?
Lua
any(data, {
.tag == "temp1" &&
float(.value) >= 1000 &&
.tag == "temp2" &&
float(.value) >= 1000
}
)- 传感器 1、传感器 2 的温度和是否大于 2000?
Lua
sum(data | filter(.tag == "temp1" || .tag == "temp2") | map(float(.value)))解释:”|” 是管道操作符,表示将上一个的操作结果作为输入进入下一个流程。filter 是过滤器,可以根据条件来过滤数据。map 是筛选器,用于删选某个字段。
下面是过滤器 filter 的使用示例:
Lua
data | filter(.tag == "temp1" || .tag == "temp2")Lua
[
{
"alias": "传感器1-温度",
"lastFetchTime": 1733891949048,
"slaverId": 1,
"tag": "temp1",
"value": "1111.1000"
},
{
"alias": "传感器1-温度",
"lastFetchTime": 1733891949303,
"slaverId": 2,
"tag": "temp2",
"value": "1000.0000"
}
]map 操作是为了返回新的 value 列表:
Lua
(data | filter(.tag == "temp1" || .tag == "temp2") | map(float(.value)))返回:
Lua
[
1111.1,
1000
]sum 则是求和:
Lua
sum(data | filter(.tag == "temp1" || .tag == "temp2") | map(float(.value)))总结
用户可以根据上述教程初步入门规则表达式。
上述三个示例已经足以入门,如果想了解高级用法请看更详细的教程:https://expr-lang.org/docs/language-definition, 或者使用 expr playground 调试模拟:https://expr-lang.org/playground