소스 검색

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

puhui999 4 달 전
부모
커밋
a42202e7eb

+ 5 - 5
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
             return false;
         }
 
-        // 1.3 检查标识符是否匹配
-        String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
-        if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
-            IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " +
-                    trigger.getIdentifier() + ", 实际: " + messageIdentifier);
+        // 1.3 检查消息中是否包含触发器指定的属性标识符
+        // 注意:属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中
+        if (!IotDeviceMessageUtils.containsIdentifier(message, trigger.getIdentifier())) {
+            IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息中不包含属性: " +
+                    trigger.getIdentifier());
             return false;
         }
 

+ 50 - 0
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;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.system.SystemUtil;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
 
@@ -69,6 +70,55 @@ public class IotDeviceMessageUtils {
         return null;
     }
 
+    /**
+     * 判断消息中是否包含指定的标识符
+     *
+     * 对于不同消息类型的处理:
+     * - EVENT_POST/SERVICE_INVOKE:检查 params.identifier 是否匹配
+     * - STATE_UPDATE:检查 params.state 是否匹配
+     * - PROPERTY_POST:检查 params 中是否包含该属性 key
+     *
+     * @param message    消息
+     * @param identifier 要检查的标识符
+     * @return 是否包含
+     */
+    public static boolean containsIdentifier(IotDeviceMessage message, String identifier) {
+        if (message.getParams() == null || StrUtil.isBlank(identifier)) {
+            return false;
+        }
+        // EVENT_POST / SERVICE_INVOKE / STATE_UPDATE:使用原有逻辑
+        String messageIdentifier = getIdentifier(message);
+        if (messageIdentifier != null) {
+            return identifier.equals(messageIdentifier);
+        }
+        // PROPERTY_POST:检查 params 中是否包含该属性 key
+        if (StrUtil.equals(message.getMethod(), IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod())) {
+            Map<String, Object> params = parseParamsToMap(message.getParams());
+            return params != null && params.containsKey(identifier);
+        }
+        return false;
+    }
+
+    /**
+     * 将 params 解析为 Map
+     *
+     * @param params 参数(可能是 Map 或 JSON 字符串)
+     * @return Map,解析失败返回 null
+     */
+    @SuppressWarnings("unchecked")
+    private static Map<String, Object> parseParamsToMap(Object params) {
+        if (params instanceof Map) {
+            return (Map<String, Object>) params;
+        }
+        if (params instanceof String) {
+            try {
+                return JsonUtils.parseObject((String) params, Map.class);
+            } catch (Exception ignored) {
+            }
+        }
+        return null;
+    }
+
     /**
      * 从设备消息中提取指定标识符的属性值
      * - 支持多种消息格式和属性值提取策略