Commit a42202e7eb9990e62a0e4d24e4b76c68134cc2b6

Authored by puhui999
1 parent a7f655e1

fix:【iot】属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotDevicePropertyPostTriggerMatcher.java
... ... @@ -36,11 +36,11 @@ public class IotDevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerM
36 36 return false;
37 37 }
38 38  
39   - // 1.3 检查标识符是否匹配
40   - String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
41   - if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
42   - IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " +
43   - trigger.getIdentifier() + ", 实际: " + messageIdentifier);
  39 + // 1.3 检查消息中是否包含触发器指定的属性标识符
  40 + // 注意:属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中
  41 + if (!IotDeviceMessageUtils.containsIdentifier(message, trigger.getIdentifier())) {
  42 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息中不包含属性: " +
  43 + trigger.getIdentifier());
44 44 return false;
45 45 }
46 46  
... ...
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/util/IotDeviceMessageUtils.java
... ... @@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil;
5 5 import cn.hutool.core.util.IdUtil;
6 6 import cn.hutool.core.util.StrUtil;
7 7 import cn.hutool.system.SystemUtil;
  8 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 9 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
9 10 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
10 11  
... ... @@ -70,6 +71,55 @@ public class IotDeviceMessageUtils {
70 71 }
71 72  
72 73 /**
  74 + * 判断消息中是否包含指定的标识符
  75 + *
  76 + * 对于不同消息类型的处理:
  77 + * - EVENT_POST/SERVICE_INVOKE:检查 params.identifier 是否匹配
  78 + * - STATE_UPDATE:检查 params.state 是否匹配
  79 + * - PROPERTY_POST:检查 params 中是否包含该属性 key
  80 + *
  81 + * @param message 消息
  82 + * @param identifier 要检查的标识符
  83 + * @return 是否包含
  84 + */
  85 + public static boolean containsIdentifier(IotDeviceMessage message, String identifier) {
  86 + if (message.getParams() == null || StrUtil.isBlank(identifier)) {
  87 + return false;
  88 + }
  89 + // EVENT_POST / SERVICE_INVOKE / STATE_UPDATE:使用原有逻辑
  90 + String messageIdentifier = getIdentifier(message);
  91 + if (messageIdentifier != null) {
  92 + return identifier.equals(messageIdentifier);
  93 + }
  94 + // PROPERTY_POST:检查 params 中是否包含该属性 key
  95 + if (StrUtil.equals(message.getMethod(), IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod())) {
  96 + Map<String, Object> params = parseParamsToMap(message.getParams());
  97 + return params != null && params.containsKey(identifier);
  98 + }
  99 + return false;
  100 + }
  101 +
  102 + /**
  103 + * 将 params 解析为 Map
  104 + *
  105 + * @param params 参数(可能是 Map 或 JSON 字符串)
  106 + * @return Map,解析失败返回 null
  107 + */
  108 + @SuppressWarnings("unchecked")
  109 + private static Map<String, Object> parseParamsToMap(Object params) {
  110 + if (params instanceof Map) {
  111 + return (Map<String, Object>) params;
  112 + }
  113 + if (params instanceof String) {
  114 + try {
  115 + return JsonUtils.parseObject((String) params, Map.class);
  116 + } catch (Exception ignored) {
  117 + }
  118 + }
  119 + return null;
  120 + }
  121 +
  122 + /**
73 123 * 从设备消息中提取指定标识符的属性值
74 124 * - 支持多种消息格式和属性值提取策略
75 125 * - 兼容现有的消息结构
... ...