607 lines
15 KiB
Markdown
607 lines
15 KiB
Markdown
# FastBee IoT平台 - 规则引擎原理与操作说明
|
||
|
||
## 一、规则引擎概述
|
||
|
||
**规则引擎**是FastBee IoT平台的核心组件,用于处理设备数据、实现场景联动、数据转发等功能。它基于**LiteFlow**框架,支持Groovy脚本,通过EL表达式构建规则链,实现灵活的业务逻辑处理。
|
||
|
||
### 核心特性
|
||
- **基于LiteFlow**: 轻量级规则引擎框架
|
||
- **Groovy脚本**: 支持动态脚本执行
|
||
- **EL表达式**: 使用表达式语言构建规则链
|
||
- **异步执行**: 非阻塞式规则执行
|
||
- **动态构建**: 运行时动态创建规则链和脚本节点
|
||
|
||
## 二、规则引擎工作原理
|
||
|
||
### 2.1 整体架构
|
||
|
||
```
|
||
设备上报数据
|
||
↓
|
||
数据处理器 (DataHandler)
|
||
↓
|
||
规则引擎处理器 (RuleEngineHandler)
|
||
↓
|
||
查询关联规则 (Script/Scene)
|
||
↓
|
||
构建规则链 (LiteFlow)
|
||
↓
|
||
执行规则脚本 (Groovy)
|
||
↓
|
||
执行动作 (设备控制/告警/转发等)
|
||
```
|
||
|
||
### 2.2 核心组件
|
||
|
||
#### 1. FlowLogExecutor(规则执行器)
|
||
- **位置**: `fastbee-plugs/fastbee-ruleEngine/src/main/java/com/fastbee/ruleEngine/core/FlowLogExecutor.java`
|
||
- **作用**: 封装LiteFlow执行器,提供日志记录功能
|
||
- **功能**:
|
||
- 执行规则链
|
||
- 记录执行日志
|
||
- 处理执行结果
|
||
|
||
#### 2. SceneContext(场景上下文)
|
||
- **位置**: `fastbee-iot-data/src/main/java/com/fastbee/iot/data/ruleEngine/SceneContext.java`
|
||
- **作用**: 场景联动的执行上下文
|
||
- **包含数据**:
|
||
- 设备编号
|
||
- 产品ID
|
||
- 数据类型(属性/功能/事件)
|
||
- 物模型数据列表
|
||
|
||
#### 3. MsgContext(消息上下文)
|
||
- **位置**: `fastbee-plugs/fastbee-ruleEngine/src/main/java/com/fastbee/ruleEngine/context/MsgContext.java`
|
||
- **作用**: 规则脚本的消息上下文
|
||
- **包含数据**:
|
||
- 主题(topic)
|
||
- 负载(payload)
|
||
- 设备编号
|
||
- 产品ID
|
||
- 协议编码
|
||
|
||
### 2.3 规则链构建原理
|
||
|
||
#### EL表达式语法
|
||
|
||
规则引擎使用EL(Expression Language)表达式来构建规则链,支持以下语法:
|
||
|
||
1. **IF-THEN结构**
|
||
```
|
||
IF(条件, THEN(动作1, 动作2))
|
||
```
|
||
|
||
2. **逻辑运算符**
|
||
- `AND(条件1, 条件2, ...)`: 所有条件都满足
|
||
- `OR(条件1, 条件2, ...)`: 任一条件满足
|
||
- `NOT(条件)`: 条件不满足
|
||
|
||
3. **执行模式**
|
||
- `THEN(动作1, 动作2, ...)`: 串行执行(顺序执行)
|
||
- `WHEN(动作1, 动作2, ...)`: 并行执行(同时执行)
|
||
|
||
#### 规则链示例
|
||
|
||
**场景联动规则链**:
|
||
```
|
||
IF(AND(T1, T2, T3), THEN(A1, A2, A3))
|
||
```
|
||
- `T1, T2, T3`: 触发器脚本(条件判断)
|
||
- `A1, A2, A3`: 执行动作脚本(执行操作)
|
||
|
||
**数据流规则链**:
|
||
```
|
||
THEN(script1, script2, httpBridge)
|
||
```
|
||
- `script1, script2`: 数据处理脚本
|
||
- `httpBridge`: HTTP桥接节点
|
||
|
||
### 2.4 脚本类型
|
||
|
||
#### 1. 脚本用途(scriptPurpose)
|
||
- `1`: 数据流 - 处理设备上报数据
|
||
- `2`: 触发器 - 条件判断脚本(返回boolean)
|
||
- `3`: 执行动作 - 执行操作脚本
|
||
|
||
#### 2. 脚本类型(scriptType)
|
||
- `script`: 普通脚本
|
||
- `boolean_script`: 条件脚本(返回boolean值)
|
||
- `switch_script`: 选择脚本
|
||
- `for_script`: 循环脚本
|
||
|
||
#### 3. 脚本事件(scriptEvent)
|
||
- `1`: 设备上报
|
||
- `2`: 平台下发
|
||
- `3`: 设备上线
|
||
- `4`: 设备离线
|
||
- `5`: HTTP桥接数据
|
||
- `6`: MQTT桥接数据
|
||
|
||
#### 4. 脚本动作(scriptAction)
|
||
- `1`: 消息重发
|
||
- `2`: 消息通知
|
||
- `3`: HTTP推送
|
||
- `4`: MQTT桥接
|
||
- `5`: 数据库存储
|
||
|
||
### 2.5 执行流程详解
|
||
|
||
#### 场景联动执行流程
|
||
|
||
```
|
||
1. 设备上报数据
|
||
↓
|
||
2. RuleEngineHandler.ruleMatch() 接收数据
|
||
↓
|
||
3. 查询设备关联的场景
|
||
sceneDeviceService.selectTriggerDeviceRelateScenes()
|
||
↓
|
||
4. 遍历场景列表
|
||
↓
|
||
5. 创建SceneContext上下文
|
||
↓
|
||
6. 执行规则链
|
||
flowExecutor.execute2FutureWithRid(chainName, context)
|
||
↓
|
||
7. LiteFlow解析EL表达式
|
||
例如: IF(AND(T1, T2), THEN(A1, A2))
|
||
↓
|
||
8. 执行触发器脚本(T1, T2)
|
||
- 检查静默时间
|
||
- 匹配设备数据
|
||
- 判断条件是否满足
|
||
↓
|
||
9. 如果条件满足,执行动作脚本(A1, A2)
|
||
- 设备控制
|
||
- 告警推送
|
||
- 场景恢复等
|
||
```
|
||
|
||
#### 规则脚本执行流程
|
||
|
||
```
|
||
1. 设备上报数据
|
||
↓
|
||
2. RuleProcess.processRuleScript() 处理
|
||
↓
|
||
3. 查询匹配的规则脚本
|
||
selectExecRuleScriptList(scriptCondition)
|
||
↓
|
||
4. 构建规则链
|
||
LiteFlowChainELBuilder.createChain()
|
||
↓
|
||
5. 执行脚本
|
||
flowExecutor.execute2RespWithRid()
|
||
↓
|
||
6. 执行脚本动作
|
||
- HTTP推送
|
||
- MQTT桥接
|
||
- 数据库存储等
|
||
```
|
||
|
||
## 三、规则引擎操作指南
|
||
|
||
### 3.1 规则脚本管理
|
||
|
||
**功能位置**: 规则引擎 → 规则脚本
|
||
**路径**: `/iot/scene/script`
|
||
**权限**: `iot:script:list`
|
||
|
||
#### 创建规则脚本
|
||
|
||
1. **进入规则脚本页面**
|
||
- 点击"新增"按钮
|
||
|
||
2. **配置脚本基本信息**
|
||
- **脚本名称**: 脚本的显示名称
|
||
- **脚本标识**: 唯一标识(字母开头,可包含数字)
|
||
- **执行顺序**: 值越大优先级越高
|
||
- **脚本事件**: 选择触发事件(设备上报/平台下发/设备上线/设备离线等)
|
||
- **脚本动作**: 选择执行动作(消息重发/消息通知/HTTP推送/MQTT桥接/数据库存储)
|
||
- **脚本状态**: 启用/禁用
|
||
|
||
3. **选择关联对象**
|
||
- **产品**: 选择关联的产品(设备上报/平台下发时)
|
||
- **桥接**: 选择HTTP/MQTT桥接(桥接数据时)
|
||
|
||
4. **编写脚本代码**
|
||
- 使用Groovy语言编写
|
||
- 脚本中可以使用上下文变量
|
||
- 支持脚本验证
|
||
|
||
5. **脚本验证**
|
||
- 点击"验证"按钮检查脚本语法
|
||
- 验证通过后才能保存
|
||
|
||
6. **保存脚本**
|
||
- 点击"确定"保存脚本
|
||
- 系统会自动构建规则链
|
||
|
||
#### 脚本编写示例
|
||
|
||
**数据流脚本示例**:
|
||
```groovy
|
||
// 获取消息上下文
|
||
def msgContext = _meta.getContextBean("com.fastbee.ruleEngine.context.MsgContext")
|
||
|
||
// 获取设备编号
|
||
def serialNumber = msgContext.getSerialNumber()
|
||
|
||
// 获取产品ID
|
||
def productId = msgContext.getProductId()
|
||
|
||
// 获取消息负载
|
||
def payload = msgContext.getPayload()
|
||
|
||
// 处理数据逻辑
|
||
// ...
|
||
|
||
// 设置处理后的数据
|
||
msgContext.setPayload(processedData)
|
||
```
|
||
|
||
**条件脚本示例**:
|
||
```groovy
|
||
// 获取场景上下文
|
||
def sceneContext = _meta.getContextBean("com.fastbee.iot.data.ruleEngine.SceneContext")
|
||
|
||
// 处理规则脚本
|
||
String json = "..."; // JSON格式的脚本模板
|
||
return sceneContext.process(json);
|
||
```
|
||
|
||
#### 查看脚本日志
|
||
|
||
1. 在脚本列表中点击"日志"按钮
|
||
2. 查看脚本执行日志
|
||
3. 日志包含:
|
||
- 执行时间
|
||
- 上下文数据
|
||
- 执行步骤
|
||
- 错误信息
|
||
|
||
### 3.2 场景联动中的规则引擎
|
||
|
||
场景联动会自动使用规则引擎,用户无需直接操作规则引擎,但需要了解其工作原理:
|
||
|
||
#### 场景创建时的规则构建
|
||
|
||
1. **创建场景时**
|
||
- 系统自动为每个触发器创建规则脚本(T开头)
|
||
- 系统自动为每个执行动作创建规则脚本(A开头)
|
||
- 自动生成EL表达式
|
||
|
||
2. **规则链构建**
|
||
- 根据执行条件(或/且/非)构建IF表达式
|
||
- 根据执行方式(串行/并行)构建THEN/WHEN表达式
|
||
- 生成完整的规则链名称(chainName)
|
||
|
||
3. **动态加载**
|
||
- 规则链和脚本节点动态构建到内存
|
||
- 无需重启服务即可生效
|
||
|
||
#### EL表达式生成规则
|
||
|
||
**执行条件为"且"(所有条件满足)**:
|
||
```
|
||
IF(AND(T1, T2, T3), THEN(A1, A2))
|
||
```
|
||
|
||
**执行条件为"或"(任一条件满足)**:
|
||
```
|
||
IF(OR(T1, T2, T3), THEN(A1, A2))
|
||
```
|
||
|
||
**执行条件为"非"(条件不满足)**:
|
||
```
|
||
IF(NOT(T1), THEN(A1, A2))
|
||
```
|
||
|
||
**执行方式为并行**:
|
||
```
|
||
IF(AND(T1, T2), WHEN(A1, A2))
|
||
```
|
||
|
||
### 3.3 规则脚本使用场景
|
||
|
||
#### 场景1: 数据转发
|
||
|
||
**需求**: 将设备上报的数据转发到第三方系统
|
||
|
||
**操作步骤**:
|
||
1. 创建规则脚本
|
||
2. 脚本事件选择"设备上报"
|
||
3. 脚本动作选择"HTTP推送"或"MQTT桥接"
|
||
4. 编写脚本处理数据
|
||
5. 配置桥接信息
|
||
6. 保存并启用脚本
|
||
|
||
#### 场景2: 数据转换
|
||
|
||
**需求**: 转换设备数据格式
|
||
|
||
**操作步骤**:
|
||
1. 创建规则脚本
|
||
2. 脚本事件选择"设备上报"
|
||
3. 脚本动作选择"消息重发"
|
||
4. 编写脚本转换数据格式
|
||
5. 保存并启用脚本
|
||
|
||
#### 场景3: 数据存储
|
||
|
||
**需求**: 将设备数据存储到数据库
|
||
|
||
**操作步骤**:
|
||
1. 创建规则脚本
|
||
2. 脚本事件选择"设备上报"
|
||
3. 脚本动作选择"数据库存储"
|
||
4. 编写脚本处理数据
|
||
5. 保存并启用脚本
|
||
|
||
## 四、规则引擎核心代码
|
||
|
||
### 4.1 规则执行器
|
||
|
||
```java
|
||
// FlowLogExecutor.java
|
||
@Component
|
||
public class FlowLogExecutor {
|
||
@Resource
|
||
private FlowExecutor flowExecutor;
|
||
|
||
// 执行规则链(带请求ID)
|
||
public LiteflowResponse execute2FutureWithRid(
|
||
String chainId,
|
||
Object param,
|
||
String requestId,
|
||
Object... contextBeanArray
|
||
) {
|
||
// 打印上下文
|
||
printContextBeanWithRid(requestId, contextBeanArray);
|
||
// 执行规则链
|
||
Future<LiteflowResponse> future =
|
||
flowExecutor.execute2FutureWithRid(chainId, param, requestId, contextBeanArray);
|
||
LiteflowResponse response = future.get();
|
||
// 打印执行结果
|
||
printResponseWithRid(requestId, response);
|
||
return response;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.2 规则链构建
|
||
|
||
```java
|
||
// SceneServiceImpl.java
|
||
private void dynamicBuildRule(List<Script> ruleScripts, Scene scene) {
|
||
for (Script ruleScript : ruleScripts) {
|
||
if (ruleScript.getScriptPurpose() == 2) {
|
||
// 构建条件脚本节点
|
||
LiteFlowNodeBuilder.createScriptBooleanNode()
|
||
.setId(ruleScript.getScriptId())
|
||
.setName(ruleScript.getScriptName())
|
||
.setScript(ruleScript.getScriptData())
|
||
.build();
|
||
} else if (ruleScript.getScriptPurpose() == 3) {
|
||
// 构建普通脚本节点
|
||
LiteFlowNodeBuilder.createScriptNode()
|
||
.setId(ruleScript.getScriptId())
|
||
.setName(ruleScript.getScriptName())
|
||
.setScript(ruleScript.getScriptData())
|
||
.build();
|
||
}
|
||
}
|
||
// 构建规则链
|
||
LiteFlowChainELBuilder.createChain()
|
||
.setChainName(scene.getChainName())
|
||
.setEL(scene.getElData())
|
||
.build();
|
||
}
|
||
```
|
||
|
||
### 4.3 EL表达式构建
|
||
|
||
```java
|
||
// SceneServiceImpl.java
|
||
private String buildElData(Scene scene, ...) {
|
||
StringBuilder triggerBuilder = new StringBuilder();
|
||
StringBuilder actionBuilder = new StringBuilder();
|
||
|
||
// 根据执行条件构建IF表达式
|
||
switch (scene.getCond()) {
|
||
case 1: // 或
|
||
triggerBuilder.append("IF(OR(");
|
||
break;
|
||
case 2: // 且
|
||
triggerBuilder.append("IF(AND(");
|
||
break;
|
||
case 3: // 非
|
||
triggerBuilder.append("IF(NOT(");
|
||
break;
|
||
}
|
||
|
||
// 根据执行方式构建THEN/WHEN表达式
|
||
switch (scene.getExecuteMode()) {
|
||
case 1: // 串行
|
||
actionBuilder.append(",THEN(");
|
||
break;
|
||
case 2: // 并行
|
||
actionBuilder.append(",WHEN(");
|
||
break;
|
||
}
|
||
|
||
// 拼接触发器ID
|
||
for (SceneScript trigger : scene.getTriggers()) {
|
||
triggerBuilder.append(scriptId + ",");
|
||
}
|
||
|
||
// 拼接动作ID
|
||
for (SceneScript action : scene.getActions()) {
|
||
actionBuilder.append(scriptId + ",");
|
||
}
|
||
|
||
// 生成最终EL表达式
|
||
// 例如: IF(AND(T1,T2),THEN(A1,A2))
|
||
return triggerBuilder.append(actionBuilder).toString();
|
||
}
|
||
```
|
||
|
||
## 五、规则引擎API接口
|
||
|
||
### 5.1 规则脚本接口
|
||
|
||
- `GET /iot/script/list` - 查询规则脚本列表
|
||
- `GET /iot/script/{scriptId}` - 获取规则脚本详情
|
||
- `POST /iot/script` - 新增规则脚本
|
||
- `PUT /iot/script` - 修改规则脚本
|
||
- `DELETE /iot/script/{scriptIds}` - 删除规则脚本
|
||
- `GET /iot/script/log/{scriptId}` - 获取规则脚本日志
|
||
- `POST /iot/script/validate` - 验证规则脚本
|
||
|
||
### 5.2 场景联动接口
|
||
|
||
- `GET /iot/scene/list` - 查询场景列表
|
||
- `GET /iot/scene/{sceneId}` - 获取场景详情
|
||
- `POST /iot/scene` - 新增场景
|
||
- `PUT /iot/scene` - 修改场景
|
||
- `DELETE /iot/scene/{sceneIds}` - 删除场景
|
||
- `GET /iot/scene/log/{chainName}` - 获取场景执行日志
|
||
- `POST /iot/runtime/runScene` - 手动执行场景
|
||
|
||
## 六、规则引擎最佳实践
|
||
|
||
### 6.1 脚本编写规范
|
||
|
||
1. **脚本标识命名**
|
||
- 使用字母开头
|
||
- 可包含字母和数字
|
||
- 建议使用有意义的名称
|
||
|
||
2. **脚本代码规范**
|
||
- 使用Groovy语法
|
||
- 添加必要的注释
|
||
- 处理异常情况
|
||
- 避免死循环
|
||
|
||
3. **性能优化**
|
||
- 避免在脚本中执行耗时操作
|
||
- 使用缓存减少重复计算
|
||
- 合理使用脚本执行顺序
|
||
|
||
### 6.2 规则链设计原则
|
||
|
||
1. **触发器设计**
|
||
- 条件判断要准确
|
||
- 避免过于复杂的条件
|
||
- 合理使用静默周期
|
||
|
||
2. **执行动作设计**
|
||
- 动作要独立可执行
|
||
- 避免动作之间的依赖
|
||
- 合理选择串行/并行执行
|
||
|
||
3. **规则链优化**
|
||
- 减少不必要的规则链
|
||
- 合并相似的规则
|
||
- 定期清理无效规则
|
||
|
||
### 6.3 调试技巧
|
||
|
||
1. **查看执行日志**
|
||
- 在脚本列表中查看日志
|
||
- 在场景列表中查看日志
|
||
- 日志包含详细的执行信息
|
||
|
||
2. **脚本验证**
|
||
- 保存前先验证脚本
|
||
- 检查语法错误
|
||
- 验证上下文变量
|
||
|
||
3. **测试规则**
|
||
- 使用测试接口测试规则
|
||
- 模拟设备数据上报
|
||
- 验证规则执行结果
|
||
|
||
## 七、规则引擎与场景联动的关系
|
||
|
||
### 7.1 关系说明
|
||
|
||
- **场景联动**是规则引擎的**应用场景**
|
||
- **规则引擎**是场景联动的**执行引擎**
|
||
- 场景联动配置会自动转换为规则引擎的规则链
|
||
|
||
### 7.2 工作流程
|
||
|
||
```
|
||
用户配置场景联动
|
||
↓
|
||
系统自动构建规则脚本
|
||
↓
|
||
生成EL表达式规则链
|
||
↓
|
||
设备上报数据触发规则
|
||
↓
|
||
规则引擎执行规则链
|
||
↓
|
||
执行场景联动动作
|
||
```
|
||
|
||
### 7.3 规则脚本分类
|
||
|
||
在场景联动中,规则脚本分为两类:
|
||
|
||
1. **触发器脚本(T开头)**
|
||
- 用途:条件判断
|
||
- 类型:boolean_script
|
||
- 返回:true/false
|
||
|
||
2. **执行动作脚本(A开头)**
|
||
- 用途:执行操作
|
||
- 类型:script
|
||
- 执行:设备控制、告警推送等
|
||
|
||
## 八、注意事项
|
||
|
||
1. **脚本安全**
|
||
- 脚本执行有安全限制
|
||
- 不允许执行危险操作
|
||
- 系统会自动替换危险包引用
|
||
|
||
2. **性能考虑**
|
||
- 规则脚本执行是异步的
|
||
- 避免在脚本中执行耗时操作
|
||
- 大量规则可能影响性能
|
||
|
||
3. **规则链管理**
|
||
- 规则链动态构建到内存
|
||
- 修改场景后规则链会自动更新
|
||
- 删除场景会清理相关规则链
|
||
|
||
4. **日志管理**
|
||
- 规则执行日志存储在logs/rule目录
|
||
- 定期清理日志文件
|
||
- 日志文件可能较大
|
||
|
||
5. **脚本语言**
|
||
- 目前主要支持Groovy
|
||
- 未来可能支持其他语言(JS、Python等)
|
||
|
||
6. **规则链命名**
|
||
- 场景规则链:C + 雪花算法ID
|
||
- 数据流规则链:dataChain_ + scriptId
|
||
- 规则链名称唯一
|
||
|
||
---
|
||
|
||
**文档版本**: v1.0
|
||
**最后更新**: 2024-12-20
|
||
**维护者**: FastBee开发团队
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|