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