15 KiB
15 KiB
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)表达式来构建规则链,支持以下语法:
-
IF-THEN结构
IF(条件, THEN(动作1, 动作2)) -
逻辑运算符
AND(条件1, 条件2, ...): 所有条件都满足OR(条件1, 条件2, ...): 任一条件满足NOT(条件): 条件不满足
-
执行模式
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
创建规则脚本
-
进入规则脚本页面
- 点击"新增"按钮
-
配置脚本基本信息
- 脚本名称: 脚本的显示名称
- 脚本标识: 唯一标识(字母开头,可包含数字)
- 执行顺序: 值越大优先级越高
- 脚本事件: 选择触发事件(设备上报/平台下发/设备上线/设备离线等)
- 脚本动作: 选择执行动作(消息重发/消息通知/HTTP推送/MQTT桥接/数据库存储)
- 脚本状态: 启用/禁用
-
选择关联对象
- 产品: 选择关联的产品(设备上报/平台下发时)
- 桥接: 选择HTTP/MQTT桥接(桥接数据时)
-
编写脚本代码
- 使用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)
条件脚本示例:
// 获取场景上下文
def sceneContext = _meta.getContextBean("com.fastbee.iot.data.ruleEngine.SceneContext")
// 处理规则脚本
String json = "..."; // JSON格式的脚本模板
return sceneContext.process(json);
查看脚本日志
- 在脚本列表中点击"日志"按钮
- 查看脚本执行日志
- 日志包含:
- 执行时间
- 上下文数据
- 执行步骤
- 错误信息
3.2 场景联动中的规则引擎
场景联动会自动使用规则引擎,用户无需直接操作规则引擎,但需要了解其工作原理:
场景创建时的规则构建
-
创建场景时
- 系统自动为每个触发器创建规则脚本(T开头)
- 系统自动为每个执行动作创建规则脚本(A开头)
- 自动生成EL表达式
-
规则链构建
- 根据执行条件(或/且/非)构建IF表达式
- 根据执行方式(串行/并行)构建THEN/WHEN表达式
- 生成完整的规则链名称(chainName)
-
动态加载
- 规则链和脚本节点动态构建到内存
- 无需重启服务即可生效
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: 数据转发
需求: 将设备上报的数据转发到第三方系统
操作步骤:
- 创建规则脚本
- 脚本事件选择"设备上报"
- 脚本动作选择"HTTP推送"或"MQTT桥接"
- 编写脚本处理数据
- 配置桥接信息
- 保存并启用脚本
场景2: 数据转换
需求: 转换设备数据格式
操作步骤:
- 创建规则脚本
- 脚本事件选择"设备上报"
- 脚本动作选择"消息重发"
- 编写脚本转换数据格式
- 保存并启用脚本
场景3: 数据存储
需求: 将设备数据存储到数据库
操作步骤:
- 创建规则脚本
- 脚本事件选择"设备上报"
- 脚本动作选择"数据库存储"
- 编写脚本处理数据
- 保存并启用脚本
四、规则引擎核心代码
4.1 规则执行器
// 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 规则链构建
// 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表达式构建
// 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 脚本编写规范
-
脚本标识命名
- 使用字母开头
- 可包含字母和数字
- 建议使用有意义的名称
-
脚本代码规范
- 使用Groovy语法
- 添加必要的注释
- 处理异常情况
- 避免死循环
-
性能优化
- 避免在脚本中执行耗时操作
- 使用缓存减少重复计算
- 合理使用脚本执行顺序
6.2 规则链设计原则
-
触发器设计
- 条件判断要准确
- 避免过于复杂的条件
- 合理使用静默周期
-
执行动作设计
- 动作要独立可执行
- 避免动作之间的依赖
- 合理选择串行/并行执行
-
规则链优化
- 减少不必要的规则链
- 合并相似的规则
- 定期清理无效规则
6.3 调试技巧
-
查看执行日志
- 在脚本列表中查看日志
- 在场景列表中查看日志
- 日志包含详细的执行信息
-
脚本验证
- 保存前先验证脚本
- 检查语法错误
- 验证上下文变量
-
测试规则
- 使用测试接口测试规则
- 模拟设备数据上报
- 验证规则执行结果
七、规则引擎与场景联动的关系
7.1 关系说明
- 场景联动是规则引擎的应用场景
- 规则引擎是场景联动的执行引擎
- 场景联动配置会自动转换为规则引擎的规则链
7.2 工作流程
用户配置场景联动
↓
系统自动构建规则脚本
↓
生成EL表达式规则链
↓
设备上报数据触发规则
↓
规则引擎执行规则链
↓
执行场景联动动作
7.3 规则脚本分类
在场景联动中,规则脚本分为两类:
-
触发器脚本(T开头)
- 用途:条件判断
- 类型:boolean_script
- 返回:true/false
-
执行动作脚本(A开头)
- 用途:执行操作
- 类型:script
- 执行:设备控制、告警推送等
八、注意事项
-
脚本安全
- 脚本执行有安全限制
- 不允许执行危险操作
- 系统会自动替换危险包引用
-
性能考虑
- 规则脚本执行是异步的
- 避免在脚本中执行耗时操作
- 大量规则可能影响性能
-
规则链管理
- 规则链动态构建到内存
- 修改场景后规则链会自动更新
- 删除场景会清理相关规则链
-
日志管理
- 规则执行日志存储在logs/rule目录
- 定期清理日志文件
- 日志文件可能较大
-
脚本语言
- 目前主要支持Groovy
- 未来可能支持其他语言(JS、Python等)
-
规则链命名
- 场景规则链:C + 雪花算法ID
- 数据流规则链:dataChain_ + scriptId
- 规则链名称唯一
文档版本: v1.0
最后更新: 2024-12-20
维护者: FastBee开发团队