Commit e639dbfeb7bc8963fd34014e40138383ae63a3a6

Authored by YunaiV
1 parent 67a44fd3

review:【iot 物联网】场景联动

Showing 19 changed files with 71 additions and 123 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleTriggerTypeEnum.java
@@ -19,7 +19,6 @@ import java.util.Arrays; @@ -19,7 +19,6 @@ import java.util.Arrays;
19 @Getter 19 @Getter
20 public enum IotSceneRuleTriggerTypeEnum implements ArrayValuable<Integer> { 20 public enum IotSceneRuleTriggerTypeEnum implements ArrayValuable<Integer> {
21 21
22 - // TODO @芋艿:后续“对应”部分,要 @下,等包结构梳理完;  
23 /** 22 /**
24 * 设备上下线变更 23 * 设备上下线变更
25 * 24 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java
@@ -84,13 +84,14 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -84,13 +84,14 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
84 84
85 @Override 85 @Override
86 public void updateSceneRuleStatus(Long id, Integer status) { 86 public void updateSceneRuleStatus(Long id, Integer status) {
87 - // 校验存在 87 + // 1. 校验存在
88 validateSceneRuleExists(id); 88 validateSceneRuleExists(id);
89 - // 更新状态 89 +
  90 + // 2. 更新状态
90 IotSceneRuleDO updateObj = new IotSceneRuleDO().setId(id).setStatus(status); 91 IotSceneRuleDO updateObj = new IotSceneRuleDO().setId(id).setStatus(status);
91 sceneRuleMapper.updateById(updateObj); 92 sceneRuleMapper.updateById(updateObj);
92 93
93 - // 根据状态管理定时触发器 94 + // 3. 根据状态管理定时触发器
94 if (CommonStatusEnum.isEnable(status)) { 95 if (CommonStatusEnum.isEnable(status)) {
95 // 启用时,获取完整的场景规则信息并注册定时触发器 96 // 启用时,获取完整的场景规则信息并注册定时触发器
96 IotSceneRuleDO sceneRule = sceneRuleMapper.selectById(id); 97 IotSceneRuleDO sceneRule = sceneRuleMapper.selectById(id);
@@ -105,12 +106,14 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -105,12 +106,14 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
105 106
106 @Override 107 @Override
107 public void deleteSceneRule(Long id) { 108 public void deleteSceneRule(Long id) {
108 - // 校验存在 109 + // 1. 校验存在
109 validateSceneRuleExists(id); 110 validateSceneRuleExists(id);
110 - // 删除定时触发器  
111 - timerHandler.unregisterTimerTriggers(id);  
112 - // 删除 111 +
  112 + // 2. 删除
113 sceneRuleMapper.deleteById(id); 113 sceneRuleMapper.deleteById(id);
  114 +
  115 + // 3. 删除定时触发器
  116 + timerHandler.unregisterTimerTriggers(id);
114 } 117 }
115 118
116 private void validateSceneRuleExists(Long id) { 119 private void validateSceneRuleExists(Long id) {
@@ -146,16 +149,17 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -146,16 +149,17 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
146 return sceneRuleMapper.selectListByStatus(status); 149 return sceneRuleMapper.selectListByStatus(status);
147 } 150 }
148 151
149 - // TODO 芋艿,缓存待实现 @puhui999 152 + // TODO @puhui999:缓存待实现
150 @Override 153 @Override
151 @TenantIgnore // 忽略租户隔离:因为 IotSceneRuleMessageHandler 调用时,一般未传递租户,所以需要忽略 154 @TenantIgnore // 忽略租户隔离:因为 IotSceneRuleMessageHandler 调用时,一般未传递租户,所以需要忽略
152 public List<IotSceneRuleDO> getSceneRuleListByProductIdAndDeviceIdFromCache(Long productId, Long deviceId) { 155 public List<IotSceneRuleDO> getSceneRuleListByProductIdAndDeviceIdFromCache(Long productId, Long deviceId) {
  156 + // 1. 查询启用状态的规则场景
  157 + // TODO @puhui999:这里查询 enable 的;
153 List<IotSceneRuleDO> list = sceneRuleMapper.selectList(); 158 List<IotSceneRuleDO> list = sceneRuleMapper.selectList();
154 - // 只返回启用状态的规则场景  
155 List<IotSceneRuleDO> enabledList = filterList(list, 159 List<IotSceneRuleDO> enabledList = filterList(list,
156 sceneRule -> CommonStatusEnum.isEnable(sceneRule.getStatus())); 160 sceneRule -> CommonStatusEnum.isEnable(sceneRule.getStatus()));
157 161
158 - // 根据 productKey 和 deviceName 进行匹配 162 + // 2. 根据 productKey 和 deviceName 进行匹配
159 return filterList(enabledList, sceneRule -> { 163 return filterList(enabledList, sceneRule -> {
160 if (CollUtil.isEmpty(sceneRule.getTriggers())) { 164 if (CollUtil.isEmpty(sceneRule.getTriggers())) {
161 return false; 165 return false;
@@ -164,21 +168,19 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -164,21 +168,19 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
164 for (IotSceneRuleDO.Trigger trigger : sceneRule.getTriggers()) { 168 for (IotSceneRuleDO.Trigger trigger : sceneRule.getTriggers()) {
165 // 检查触发器是否匹配指定的产品和设备 169 // 检查触发器是否匹配指定的产品和设备
166 try { 170 try {
167 - // 1. 检查产品是否匹配  
168 - if (trigger.getProductId() == null) {  
169 - return false;  
170 - }  
171 - if (trigger.getDeviceId() == null) { 171 + // 检查产品是否匹配
  172 + if (trigger.getProductId() == null || trigger.getDeviceId() == null) {
172 return false; 173 return false;
173 } 174 }
174 // 检查是否是全部设备的特殊标识 175 // 检查是否是全部设备的特殊标识
175 if (IotDeviceDO.DEVICE_ID_ALL.equals(trigger.getDeviceId())) { 176 if (IotDeviceDO.DEVICE_ID_ALL.equals(trigger.getDeviceId())) {
176 - return true; // 匹配所有设备 177 + return true;
177 } 178 }
178 // 检查具体设备 ID 是否匹配 179 // 检查具体设备 ID 是否匹配
179 return ObjUtil.equal(productId, trigger.getProductId()) && ObjUtil.equal(deviceId, trigger.getDeviceId()); 180 return ObjUtil.equal(productId, trigger.getProductId()) && ObjUtil.equal(deviceId, trigger.getDeviceId());
180 } catch (Exception e) { 181 } catch (Exception e) {
181 - log.warn("[isMatchProductAndDevice][产品({}) 设备({}) 匹配触发器异常]", productId, deviceId, e); 182 + log.warn("[getSceneRuleListByProductIdAndDeviceIdFromCache][产品({}) 设备({}) 匹配触发器异常]",
  183 + productId, deviceId, e);
182 return false; 184 return false;
183 } 185 }
184 } 186 }
@@ -188,7 +190,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -188,7 +190,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
188 190
189 @Override 191 @Override
190 public void executeSceneRuleByDevice(IotDeviceMessage message) { 192 public void executeSceneRuleByDevice(IotDeviceMessage message) {
191 - // TODO @芋艿:这里的 tenantId,通过设备获取;@puhui999: 193 + // TODO @puhui999:这里的 tenantId,通过设备获取;
192 TenantUtils.execute(message.getTenantId(), () -> { 194 TenantUtils.execute(message.getTenantId(), () -> {
193 // 1. 获得设备匹配的规则场景 195 // 1. 获得设备匹配的规则场景
194 List<IotSceneRuleDO> sceneRules = getMatchedSceneRuleListByMessage(message); 196 List<IotSceneRuleDO> sceneRules = getMatchedSceneRuleListByMessage(message);
@@ -234,7 +236,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -234,7 +236,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
234 */ 236 */
235 private List<IotSceneRuleDO> getMatchedSceneRuleListByMessage(IotDeviceMessage message) { 237 private List<IotSceneRuleDO> getMatchedSceneRuleListByMessage(IotDeviceMessage message) {
236 // 1. 匹配设备 238 // 1. 匹配设备
237 - // TODO @芋艿:可能需要 getSelf(); 缓存 @puhui999; 239 + // TODO 缓存 @puhui999:可能需要 getSelf()
238 // 1.1 通过 deviceId 获取设备信息 240 // 1.1 通过 deviceId 获取设备信息
239 IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId()); 241 IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId());
240 if (device == null) { 242 if (device == null) {
@@ -293,7 +295,6 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -293,7 +295,6 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
293 */ 295 */
294 private boolean matchSingleTrigger(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, IotSceneRuleDO sceneRule) { 296 private boolean matchSingleTrigger(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, IotSceneRuleDO sceneRule) {
295 try { 297 try {
296 - // 2. 检查触发器的条件分组  
297 return sceneRuleMatcherManager.isMatched(message, trigger) && isTriggerConditionGroupsMatched(message, trigger, sceneRule); 298 return sceneRuleMatcherManager.isMatched(message, trigger) && isTriggerConditionGroupsMatched(message, trigger, sceneRule);
298 } catch (Exception e) { 299 } catch (Exception e) {
299 log.error("[matchSingleTrigger][触发器匹配异常] sceneRuleId: {}, triggerType: {}, message: {}", 300 log.error("[matchSingleTrigger][触发器匹配异常] sceneRuleId: {}, triggerType: {}, message: {}",
@@ -310,18 +311,19 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -310,18 +311,19 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
310 * @param sceneRule 场景规则(用于日志) 311 * @param sceneRule 场景规则(用于日志)
311 * @return 是否匹配 312 * @return 是否匹配
312 */ 313 */
313 - private boolean isTriggerConditionGroupsMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, IotSceneRuleDO sceneRule) {  
314 - // 如果没有条件分组,则认为匹配成功(只依赖基础触发器匹配) 314 + private boolean isTriggerConditionGroupsMatched(IotDeviceMessage message,
  315 + IotSceneRuleDO.Trigger trigger,
  316 + IotSceneRuleDO sceneRule) {
  317 + // 1. 如果没有条件分组,则认为匹配成功(只依赖基础触发器匹配)
315 if (CollUtil.isEmpty(trigger.getConditionGroups())) { 318 if (CollUtil.isEmpty(trigger.getConditionGroups())) {
316 return true; 319 return true;
317 } 320 }
318 321
319 - // 检查条件分组:分组与分组之间是"或"的关系,条件与条件之间是"且"的关系 322 + // 2. 检查条件分组:分组与分组之间是"或"的关系,条件与条件之间是"且"的关系
320 for (List<IotSceneRuleDO.TriggerCondition> conditionGroup : trigger.getConditionGroups()) { 323 for (List<IotSceneRuleDO.TriggerCondition> conditionGroup : trigger.getConditionGroups()) {
321 if (CollUtil.isEmpty(conditionGroup)) { 324 if (CollUtil.isEmpty(conditionGroup)) {
322 continue; 325 continue;
323 } 326 }
324 -  
325 // 检查当前分组中的所有条件是否都匹配(且关系) 327 // 检查当前分组中的所有条件是否都匹配(且关系)
326 boolean allConditionsMatched = true; 328 boolean allConditionsMatched = true;
327 for (IotSceneRuleDO.TriggerCondition condition : conditionGroup) { 329 for (IotSceneRuleDO.TriggerCondition condition : conditionGroup) {
@@ -330,14 +332,13 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -330,14 +332,13 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
330 break; 332 break;
331 } 333 }
332 } 334 }
333 -  
334 // 如果当前分组的所有条件都匹配,则整个触发器匹配成功 335 // 如果当前分组的所有条件都匹配,则整个触发器匹配成功
335 if (allConditionsMatched) { 336 if (allConditionsMatched) {
336 return true; 337 return true;
337 } 338 }
338 } 339 }
339 340
340 - // 所有分组都不匹配 341 + // 3. 所有分组都不匹配
341 return false; 342 return false;
342 } 343 }
343 344
@@ -372,13 +373,13 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @@ -372,13 +373,13 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
372 sceneRules.forEach(sceneRule -> { 373 sceneRules.forEach(sceneRule -> {
373 // 2. 遍历规则场景的动作 374 // 2. 遍历规则场景的动作
374 sceneRule.getActions().forEach(actionConfig -> { 375 sceneRule.getActions().forEach(actionConfig -> {
375 - // 3.1 获取对应的动作 Action 数组 376 + // 2.1 获取对应的动作 Action 数组
376 List<IotSceneRuleAction> actions = filterList(sceneRuleActions, 377 List<IotSceneRuleAction> actions = filterList(sceneRuleActions,
377 action -> action.getType().getType().equals(actionConfig.getType())); 378 action -> action.getType().getType().equals(actionConfig.getType()));
378 if (CollUtil.isEmpty(actions)) { 379 if (CollUtil.isEmpty(actions)) {
379 return; 380 return;
380 } 381 }
381 - // 3.2 执行动作 382 + // 2.2 执行动作
382 actions.forEach(action -> { 383 actions.forEach(action -> {
383 try { 384 try {
384 action.execute(message, sceneRule, actionConfig); 385 action.execute(message, sceneRule, actionConfig);
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotAlertRecoverSceneRuleAction.java
@@ -14,7 +14,6 @@ import java.util.List; @@ -14,7 +14,6 @@ import java.util.List;
14 14
15 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 15 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
16 16
17 -// TODO @puhui999、@芋艿:未测试;需要场景联动开发完  
18 /** 17 /**
19 * IoT 告警恢复的 {@link IotSceneRuleAction} 实现类 18 * IoT 告警恢复的 {@link IotSceneRuleAction} 实现类
20 * 19 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotAlertTriggerSceneRuleAction.java
@@ -17,7 +17,6 @@ import org.springframework.stereotype.Component; @@ -17,7 +17,6 @@ import org.springframework.stereotype.Component;
17 import javax.annotation.Nullable; 17 import javax.annotation.Nullable;
18 import java.util.List; 18 import java.util.List;
19 19
20 -// TODO @puhui999、@芋艿:未测试;需要场景联动开发完  
21 /** 20 /**
22 * IoT 告警触发的 {@link IotSceneRuleAction} 实现类 21 * IoT 告警触发的 {@link IotSceneRuleAction} 实现类
23 * 22 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java
@@ -4,10 +4,8 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotScene @@ -4,10 +4,8 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotScene
4 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher; 4 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher;
5 5
6 /** 6 /**
7 - * IoT 场景规则匹配器基础接口  
8 - * <p>  
9 - * 定义所有匹配器的通用行为,包括优先级、名称和启用状态  
10 - * <p> 7 + * IoT 场景规则匹配器基础接口:定义所有匹配器的通用行为,包括优先级、名称和启用状态
  8 + *
11 * - {@link IotSceneRuleTriggerMatcher} 触发器匹配器 9 * - {@link IotSceneRuleTriggerMatcher} 触发器匹配器
12 * - {@link IotSceneRuleConditionMatcher} 条件匹配器 10 * - {@link IotSceneRuleConditionMatcher} 条件匹配器
13 * 11 *
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java
@@ -18,10 +18,8 @@ import java.util.Map; @@ -18,10 +18,8 @@ import java.util.Map;
18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
19 19
20 /** 20 /**
21 - * IoT 场景规则匹配器工具类  
22 - * <p>  
23 - * 提供通用的条件评估逻辑和工具方法,供触发器和条件匹配器使用  
24 - * <p> 21 + * IoT 场景规则匹配器工具类:提供通用的条件评估逻辑和工具方法,供触发器和条件匹配器使用
  22 + *
25 * 该类包含了匹配器实现中常用的工具方法,如条件评估、参数校验、日志记录等 23 * 该类包含了匹配器实现中常用的工具方法,如条件评估、参数校验、日志记录等
26 * 24 *
27 * @author HUIHUI 25 * @author HUIHUI
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
@@ -16,9 +16,7 @@ import java.util.function.Function; @@ -16,9 +16,7 @@ import java.util.function.Function;
16 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 16 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
17 17
18 /** 18 /**
19 - * IoT 场景规则匹配器统一管理器  
20 - * <p>  
21 - * 负责管理所有匹配器(触发器匹配器和条件匹配器),并提供统一的匹配入口 19 + * IoT 场景规则匹配器统一管理器:负责管理所有匹配器(触发器匹配器和条件匹配器),并提供统一的匹配入口
22 * 20 *
23 * @author HUIHUI 21 * @author HUIHUI
24 */ 22 */
@@ -44,13 +42,12 @@ public class IotSceneRuleMatcherManager { @@ -44,13 +42,12 @@ public class IotSceneRuleMatcherManager {
44 return; 42 return;
45 } 43 }
46 44
47 - // 按优先级排序并过滤启用的匹配器 45 + // 1.1 按优先级排序并过滤启用的匹配器
48 List<IotSceneRuleMatcher> allMatchers = matchers.stream() 46 List<IotSceneRuleMatcher> allMatchers = matchers.stream()
49 .filter(IotSceneRuleMatcher::isEnabled) 47 .filter(IotSceneRuleMatcher::isEnabled)
50 .sorted(Comparator.comparing(IotSceneRuleMatcher::getPriority)) 48 .sorted(Comparator.comparing(IotSceneRuleMatcher::getPriority))
51 .toList(); 49 .toList();
52 -  
53 - // 分离触发器匹配器和条件匹配器 50 + // 1.2 分离触发器匹配器和条件匹配器
54 List<IotSceneRuleTriggerMatcher> triggerMatchers = allMatchers.stream() 51 List<IotSceneRuleTriggerMatcher> triggerMatchers = allMatchers.stream()
55 .filter(matcher -> matcher instanceof IotSceneRuleTriggerMatcher) 52 .filter(matcher -> matcher instanceof IotSceneRuleTriggerMatcher)
56 .map(matcher -> (IotSceneRuleTriggerMatcher) matcher) 53 .map(matcher -> (IotSceneRuleTriggerMatcher) matcher)
@@ -60,7 +57,7 @@ public class IotSceneRuleMatcherManager { @@ -60,7 +57,7 @@ public class IotSceneRuleMatcherManager {
60 .map(matcher -> (IotSceneRuleConditionMatcher) matcher) 57 .map(matcher -> (IotSceneRuleConditionMatcher) matcher)
61 .toList(); 58 .toList();
62 59
63 - // 构建触发器匹配器映射表 60 + // 2.1 构建触发器匹配器映射表
64 this.triggerMatchers = convertMap(triggerMatchers, IotSceneRuleTriggerMatcher::getSupportedTriggerType, 61 this.triggerMatchers = convertMap(triggerMatchers, IotSceneRuleTriggerMatcher::getSupportedTriggerType,
65 Function.identity(), 62 Function.identity(),
66 (existing, replacement) -> { 63 (existing, replacement) -> {
@@ -70,7 +67,7 @@ public class IotSceneRuleMatcherManager { @@ -70,7 +67,7 @@ public class IotSceneRuleMatcherManager {
70 existing.getSupportedTriggerType() : replacement.getSupportedTriggerType()); 67 existing.getSupportedTriggerType() : replacement.getSupportedTriggerType());
71 return existing.getPriority() <= replacement.getPriority() ? existing : replacement; 68 return existing.getPriority() <= replacement.getPriority() ? existing : replacement;
72 }, LinkedHashMap::new); 69 }, LinkedHashMap::new);
73 - // 构建条件匹配器映射表 70 + // 2.2 构建条件匹配器映射表
74 this.conditionMatchers = convertMap(conditionMatchers, IotSceneRuleConditionMatcher::getSupportedConditionType, 71 this.conditionMatchers = convertMap(conditionMatchers, IotSceneRuleConditionMatcher::getSupportedConditionType,
75 Function.identity(), 72 Function.identity(),
76 (existing, replacement) -> { 73 (existing, replacement) -> {
@@ -82,7 +79,7 @@ public class IotSceneRuleMatcherManager { @@ -82,7 +79,7 @@ public class IotSceneRuleMatcherManager {
82 }, 79 },
83 LinkedHashMap::new); 80 LinkedHashMap::new);
84 81
85 - // 日志输出初始化信息 82 + // 3. 日志输出初始化信息
86 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载({})个匹配器,其中触发器匹配器({})个,条件匹配器({})个]", 83 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载({})个匹配器,其中触发器匹配器({})个,条件匹配器({})个]",
87 allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size()); 84 allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size());
88 this.triggerMatchers.forEach((type, matcher) -> 85 this.triggerMatchers.forEach((type, matcher) ->
@@ -135,7 +132,7 @@ public class IotSceneRuleMatcherManager { @@ -135,7 +132,7 @@ public class IotSceneRuleMatcherManager {
135 return false; 132 return false;
136 } 133 }
137 134
138 - // 根据条件类型查找对应的匹配器 135 + // 1. 根据条件类型查找对应的匹配器
139 IotSceneRuleConditionTypeEnum conditionType = IotSceneRuleConditionTypeEnum.typeOf(condition.getType()); 136 IotSceneRuleConditionTypeEnum conditionType = IotSceneRuleConditionTypeEnum.typeOf(condition.getType());
140 if (conditionType == null) { 137 if (conditionType == null) {
141 log.warn("[isConditionMatched][conditionType({}) 未知的条件类型]", condition.getType()); 138 log.warn("[isConditionMatched][conditionType({}) 未知的条件类型]", condition.getType());
@@ -147,7 +144,7 @@ public class IotSceneRuleMatcherManager { @@ -147,7 +144,7 @@ public class IotSceneRuleMatcherManager {
147 return false; 144 return false;
148 } 145 }
149 146
150 - // 执行匹配逻辑 147 + // 2. 执行匹配逻辑
151 try { 148 try {
152 return matcher.matches(message, condition); 149 return matcher.matches(message, condition);
153 } catch (Exception e) { 150 } catch (Exception e) {
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/CurrentTimeConditionMatcher.java
@@ -16,10 +16,9 @@ import java.time.LocalTime; @@ -16,10 +16,9 @@ import java.time.LocalTime;
16 import java.time.format.DateTimeFormatter; 16 import java.time.format.DateTimeFormatter;
17 import java.util.List; 17 import java.util.List;
18 18
  19 +// TODO @puhui999:是不是 IoT 的前缀,都加下哈;
19 /** 20 /**
20 - * 当前时间条件匹配器  
21 - * <p>  
22 - * 处理时间相关的子条件匹配逻辑 21 + * 当前时间条件匹配器:处理时间相关的子条件匹配逻辑
23 * 22 *
24 * @author HUIHUI 23 * @author HUIHUI
25 */ 24 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DevicePropertyConditionMatcher.java
@@ -10,9 +10,7 @@ import org.springframework.stereotype.Component; @@ -10,9 +10,7 @@ import org.springframework.stereotype.Component;
10 10
11 11
12 /** 12 /**
13 - * 设备属性条件匹配器  
14 - * <p>  
15 - * 处理设备属性相关的子条件匹配逻辑 13 + * 设备属性条件匹配器:处理设备属性相关的子条件匹配逻辑
16 * 14 *
17 * @author HUIHUI 15 * @author HUIHUI
18 */ 16 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DeviceStateConditionMatcher.java
@@ -8,9 +8,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche @@ -8,9 +8,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
9 9
10 /** 10 /**
11 - * 设备状态条件匹配器  
12 - * <p>  
13 - * 处理设备状态相关的子条件匹配逻辑 11 + * 设备状态条件匹配器:处理设备状态相关的子条件匹配逻辑
14 * 12 *
15 * @author HUIHUI 13 * @author HUIHUI
16 */ 14 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotSceneRuleConditionMatcher.java
@@ -6,12 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; @@ -6,12 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
6 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher; 6 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
7 7
8 /** 8 /**
9 - * IoT 场景规则条件匹配器接口  
10 - * <p>  
11 - * 专门处理子条件的匹配逻辑,如设备状态、属性值、时间条件等  
12 - * <p>  
13 - * 条件匹配器负责判断设备消息是否满足场景规则的附加条件,  
14 - * 在触发器匹配成功后进行进一步的条件筛选 9 + * IoT 场景规则条件匹配器接口:专门处理子条件的匹配逻辑,如设备状态、属性值、时间条件等
  10 + *
  11 + * 条件匹配器负责判断设备消息是否满足场景规则的附加条件,在触发器匹配成功后进行进一步的条件筛选
15 * 12 *
16 * @author HUIHUI 13 * @author HUIHUI
17 */ 14 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
@@ -10,9 +10,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche @@ -10,9 +10,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
10 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
11 11
12 /** 12 /**
13 - * 设备事件上报触发器匹配器  
14 - * <p>  
15 - * 处理设备事件上报的触发器匹配逻辑 13 + * 设备事件上报触发器匹配器:处理设备事件上报的触发器匹配逻辑
16 * 14 *
17 * @author HUIHUI 15 * @author HUIHUI
18 */ 16 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
@@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 /** 11 /**
12 - * 设备属性上报触发器匹配器  
13 - * <p>  
14 - * 处理设备属性数据上报的触发器匹配逻辑 12 + * 设备属性上报触发器匹配器:处理设备属性数据上报的触发器匹配逻辑
15 * 13 *
16 * @author HUIHUI 14 * @author HUIHUI
17 */ 15 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
@@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 /** 11 /**
12 - * 设备服务调用触发器匹配器  
13 - * <p>  
14 - * 处理设备服务调用的触发器匹配逻辑 12 + * 设备服务调用触发器匹配器:处理设备服务调用的触发器匹配逻辑
15 * 13 *
16 * @author HUIHUI 14 * @author HUIHUI
17 */ 15 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
@@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 /** 11 /**
12 - * 设备状态更新触发器匹配器  
13 - * <p>  
14 - * 处理设备上下线状态变更的触发器匹配逻辑 12 + * 设备状态更新触发器匹配器:处理设备上下线状态变更的触发器匹配逻辑
15 * 13 *
16 * @author HUIHUI 14 * @author HUIHUI
17 */ 15 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java
@@ -6,12 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; @@ -6,12 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
6 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher; 6 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
7 7
8 /** 8 /**
9 - * IoT 场景规则触发器匹配器接口  
10 - * <p>  
11 - * 专门处理主触发条件的匹配逻辑,如设备消息类型、定时器等  
12 - * <p>  
13 - * 触发器匹配器负责判断设备消息是否满足场景规则的主触发条件,  
14 - * 是场景规则执行的第一道门槛 9 + * IoT 场景规则触发器匹配器接口:专门处理主触发条件的匹配逻辑,如设备消息类型、定时器等
  10 + *
  11 + * 触发器匹配器负责判断设备消息是否满足场景规则的主触发条件,是场景规则执行的第一道门槛
15 * 12 *
16 * @author HUIHUI 13 * @author HUIHUI
17 */ 14 */
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
@@ -9,9 +9,8 @@ import org.quartz.CronExpression; @@ -9,9 +9,8 @@ import org.quartz.CronExpression;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 /** 11 /**
12 - * 定时触发器匹配器  
13 - * <p>  
14 - * 处理定时触发的触发器匹配逻辑 12 + * 定时触发器匹配器:处理定时触发的触发器匹配逻辑
  13 + *
15 * 注意:定时触发器不依赖设备消息,主要用于定时任务场景 14 * 注意:定时触发器不依赖设备消息,主要用于定时任务场景
16 * 15 *
17 * @author HUIHUI 16 * @author HUIHUI
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/timer/IotSceneRuleTimerHandler.java
@@ -18,9 +18,7 @@ import java.util.List; @@ -18,9 +18,7 @@ import java.util.List;
18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; 18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
19 19
20 /** 20 /**
21 - * IoT 场景规则定时触发器处理器  
22 - * <p>  
23 - * 负责管理定时触发器的注册、更新、删除等操作 21 + * IoT 场景规则定时触发器处理器:负责管理定时触发器的注册、更新、删除等操作
24 * 22 *
25 * @author HUIHUI 23 * @author HUIHUI
26 */ 24 */
@@ -37,19 +35,17 @@ public class IotSceneRuleTimerHandler { @@ -37,19 +35,17 @@ public class IotSceneRuleTimerHandler {
37 * @param sceneRule 场景规则 35 * @param sceneRule 场景规则
38 */ 36 */
39 public void registerTimerTriggers(IotSceneRuleDO sceneRule) { 37 public void registerTimerTriggers(IotSceneRuleDO sceneRule) {
  38 + // 1. 过滤出定时触发器
40 if (sceneRule == null || CollUtil.isEmpty(sceneRule.getTriggers())) { 39 if (sceneRule == null || CollUtil.isEmpty(sceneRule.getTriggers())) {
41 return; 40 return;
42 } 41 }
43 -  
44 - // 过滤出定时触发器  
45 List<IotSceneRuleDO.Trigger> timerTriggers = filterList(sceneRule.getTriggers(), 42 List<IotSceneRuleDO.Trigger> timerTriggers = filterList(sceneRule.getTriggers(),
46 trigger -> ObjUtil.equals(trigger.getType(), IotSceneRuleTriggerTypeEnum.TIMER.getType())); 43 trigger -> ObjUtil.equals(trigger.getType(), IotSceneRuleTriggerTypeEnum.TIMER.getType()));
47 -  
48 if (CollUtil.isEmpty(timerTriggers)) { 44 if (CollUtil.isEmpty(timerTriggers)) {
49 return; 45 return;
50 } 46 }
51 47
52 - // 注册每个定时触发器 48 + // 2. 注册每个定时触发器
53 timerTriggers.forEach(trigger -> registerSingleTimerTrigger(sceneRule, trigger)); 49 timerTriggers.forEach(trigger -> registerSingleTimerTrigger(sceneRule, trigger));
54 } 50 }
55 51
@@ -63,23 +59,23 @@ public class IotSceneRuleTimerHandler { @@ -63,23 +59,23 @@ public class IotSceneRuleTimerHandler {
63 return; 59 return;
64 } 60 }
65 61
66 - // 先删除旧的定时任务 62 + // 1. 先删除旧的定时任务
67 unregisterTimerTriggers(sceneRule.getId()); 63 unregisterTimerTriggers(sceneRule.getId());
68 64
69 - // 如果场景规则已禁用,则不重新注册 65 + // 2.1 如果场景规则已禁用,则不重新注册
70 if (CommonStatusEnum.isDisable(sceneRule.getStatus())) { 66 if (CommonStatusEnum.isDisable(sceneRule.getStatus())) {
71 log.info("[updateTimerTriggers][场景规则({}) 已禁用,不注册定时触发器]", sceneRule.getId()); 67 log.info("[updateTimerTriggers][场景规则({}) 已禁用,不注册定时触发器]", sceneRule.getId());
72 return; 68 return;
73 } 69 }
74 70
75 - // 重新注册定时触发器 71 + // 2.2 重新注册定时触发器
76 registerTimerTriggers(sceneRule); 72 registerTimerTriggers(sceneRule);
77 } 73 }
78 74
79 /** 75 /**
80 * 注销场景规则的定时触发器 76 * 注销场景规则的定时触发器
81 * 77 *
82 - * @param sceneRuleId 场景规则ID 78 + * @param sceneRuleId 场景规则 ID
83 */ 79 */
84 public void unregisterTimerTriggers(Long sceneRuleId) { 80 public void unregisterTimerTriggers(Long sceneRuleId) {
85 if (sceneRuleId == null) { 81 if (sceneRuleId == null) {
@@ -98,7 +94,7 @@ public class IotSceneRuleTimerHandler { @@ -98,7 +94,7 @@ public class IotSceneRuleTimerHandler {
98 /** 94 /**
99 * 暂停场景规则的定时触发器 95 * 暂停场景规则的定时触发器
100 * 96 *
101 - * @param sceneRuleId 场景规则ID 97 + * @param sceneRuleId 场景规则 ID
102 */ 98 */
103 public void pauseTimerTriggers(Long sceneRuleId) { 99 public void pauseTimerTriggers(Long sceneRuleId) {
104 if (sceneRuleId == null) { 100 if (sceneRuleId == null) {
@@ -115,25 +111,6 @@ public class IotSceneRuleTimerHandler { @@ -115,25 +111,6 @@ public class IotSceneRuleTimerHandler {
115 } 111 }
116 112
117 /** 113 /**
118 - * 恢复场景规则的定时触发器  
119 - *  
120 - * @param sceneRuleId 场景规则ID  
121 - */  
122 - public void resumeTimerTriggers(Long sceneRuleId) {  
123 - if (sceneRuleId == null) {  
124 - return;  
125 - }  
126 -  
127 - String jobName = buildJobName(sceneRuleId);  
128 - try {  
129 - schedulerManager.resumeJob(jobName);  
130 - log.info("[resumeTimerTriggers][场景规则({}) 定时触发器恢复成功]", sceneRuleId);  
131 - } catch (SchedulerException e) {  
132 - log.error("[resumeTimerTriggers][场景规则({}) 定时触发器恢复失败]", sceneRuleId, e);  
133 - }  
134 - }  
135 -  
136 - /**  
137 * 注册单个定时触发器 114 * 注册单个定时触发器
138 * 115 *
139 * @param sceneRule 场景规则 116 * @param sceneRule 场景规则
@@ -146,18 +123,16 @@ public class IotSceneRuleTimerHandler { @@ -146,18 +123,16 @@ public class IotSceneRuleTimerHandler {
146 return; 123 return;
147 } 124 }
148 125
149 - // 2. 构建任务名称和数据  
150 - String jobName = buildJobName(sceneRule.getId());  
151 -  
152 try { 126 try {
153 - // 3. 注册定时任务 127 + // 2.1 构建任务名称和数据
  128 + String jobName = buildJobName(sceneRule.getId());
  129 + // 2.2 注册定时任务
154 schedulerManager.addOrUpdateJob( 130 schedulerManager.addOrUpdateJob(
155 IotSceneRuleJob.class, 131 IotSceneRuleJob.class,
156 jobName, 132 jobName,
157 trigger.getCronExpression(), 133 trigger.getCronExpression(),
158 IotSceneRuleJob.buildJobDataMap(sceneRule.getId()) 134 IotSceneRuleJob.buildJobDataMap(sceneRule.getId())
159 ); 135 );
160 -  
161 log.info("[registerSingleTimerTrigger][场景规则({}) 定时触发器注册成功,CRON: {}]", 136 log.info("[registerSingleTimerTrigger][场景规则({}) 定时触发器注册成功,CRON: {}]",
162 sceneRule.getId(), trigger.getCronExpression()); 137 sceneRule.getId(), trigger.getCronExpression());
163 } catch (SchedulerException e) { 138 } catch (SchedulerException e) {
@@ -169,10 +144,11 @@ public class IotSceneRuleTimerHandler { @@ -169,10 +144,11 @@ public class IotSceneRuleTimerHandler {
169 /** 144 /**
170 * 构建任务名称 145 * 构建任务名称
171 * 146 *
172 - * @param sceneRuleId 场景规则ID 147 + * @param sceneRuleId 场景规则 ID
173 * @return 任务名称 148 * @return 任务名称
174 */ 149 */
175 private String buildJobName(Long sceneRuleId) { 150 private String buildJobName(Long sceneRuleId) {
176 return "iot_scene_rule_timer_" + sceneRuleId; 151 return "iot_scene_rule_timer_" + sceneRuleId;
177 } 152 }
  153 +
178 } 154 }
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/BaseMatcherTest.java
@@ -6,6 +6,7 @@ import org.springframework.context.annotation.Bean; @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration; 6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; 7 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
8 8
  9 +// TODO @puhui999:建议改成 IotBaseConditionMatcherTest
9 /** 10 /**
10 * Matcher 测试基类 11 * Matcher 测试基类
11 * 提供通用的 Spring 测试配置 12 * 提供通用的 Spring 测试配置