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

This commit is contained in:
puhui999
2026-01-13 16:31:43 +08:00
parent a7f655e1e7
commit a42202e7eb
2 changed files with 55 additions and 5 deletions

View File

@@ -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;
}

View File

@@ -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;
}
/**
* 从设备消息中提取指定标识符的属性值
* - 支持多种消息格式和属性值提取策略