From c15cbc8c86f504bea83ea1082afd0d87bcaa70a6 Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Sun, 26 Apr 2026 23:01:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=A4=AA=E9=98=B3=E8=83=BD=E7=BD=91?= =?UTF-8?q?=E6=8E=A7=EF=BC=8C=E7=A6=BB=E7=BA=BF=E6=8A=A5=E8=AD=A6=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intc/iot/handler/DeviceDataHandler.java | 9 ++++- .../intc/iot/task/DeviceOfflineWarnTask.java | 37 ++++++++++++++++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java index 2430cb2..abd96e2 100644 --- a/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java @@ -891,8 +891,9 @@ public class DeviceDataHandler { // 查询设备类型,太阳能网控(type=3)使用独立的延迟时长 int offlineDelayMinutes = aliyunIotProperties.getOfflineWarnDelayMinutes(); + Device deviceForType = null; try { - Device deviceForType = deviceMapper.selectOne( + deviceForType = deviceMapper.selectOne( new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() .eq(Device::getSerialNum, deviceName) .select(Device::getDeviceType) @@ -908,7 +909,11 @@ public class DeviceDataHandler { String offlineTime = LocalDateTime.now().format(DATETIME_FORMATTER); int ttlMinutes = offlineDelayMinutes * OFFLINE_WAIT_TTL_MULTIPLIER; - RedisUtils.setCacheObject(redisKey, offlineTime, Duration.ofMinutes(ttlMinutes)); + // value 格式:{offlineTime}|{deviceType},定时任务根据设备类型使用对应延迟阈值 + int deviceTypeForRedis = (deviceForType != null && deviceForType.getDeviceType() != null) + ? deviceForType.getDeviceType() : 0; + String redisValue = offlineTime + "|" + deviceTypeForRedis; + RedisUtils.setCacheObject(redisKey, redisValue, Duration.ofMinutes(ttlMinutes)); log.info("[离线告警] 设备离线,已记录等待标记,将在 {} 分钟后触发告警: {}", offlineDelayMinutes, deviceName); // 同步更新 Device.warnCode,写入离线标志位 diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/task/DeviceOfflineWarnTask.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/task/DeviceOfflineWarnTask.java index 95ad6e0..070fbca 100644 --- a/intc-modules/intc-iot/src/main/java/com/intc/iot/task/DeviceOfflineWarnTask.java +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/task/DeviceOfflineWarnTask.java @@ -28,6 +28,12 @@ public class DeviceOfflineWarnTask { private static final String OFFLINE_WAIT_KEY_PREFIX = "device:offline:wait:"; + /** Redis value 分隔符,格式:{offlineTime}|{deviceType} */ + private static final String VALUE_SEPARATOR = "|"; + + /** 太阳能网控设备类型值 */ + private static final int SOLAR_CONTROLLER_TYPE = 3; + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private final DeviceDataHandler deviceDataHandler; @@ -36,7 +42,8 @@ public class DeviceOfflineWarnTask { /** * 每分钟扫描一次离线等待标记 - * 对超过配置的 offline-warn-delay-minutes 分钟的设备触发告警 + * 对超过配置的延迟时长的设备触发告警 + * Redis value 格式:{offlineTime}|{deviceType},根据设备类型使用对应延迟时长 */ @Scheduled(fixedDelay = 60000) public void checkOfflineWaitAndTrigger() { @@ -49,22 +56,42 @@ public class DeviceOfflineWarnTask { LocalDateTime now = LocalDateTime.now(); for (String key : keys) { try { - String offlineTimeStr = RedisUtils.getCacheObject(key); - if (offlineTimeStr == null) { + String value = RedisUtils.getCacheObject(key); + if (value == null) { continue; } + // 解析 value,兼容旧格式(纯时间字符串)和新格式(时间|设备类型) + String offlineTimeStr; + int deviceType = 0; + if (value.contains(VALUE_SEPARATOR)) { + String[] parts = value.split("\\" + VALUE_SEPARATOR, 2); + offlineTimeStr = parts[0]; + try { + deviceType = Integer.parseInt(parts[1]); + } catch (NumberFormatException ignore) { + } + } else { + // 旧格式兼容:纯时间字符串,设备类型未知,使用默认延迟 + offlineTimeStr = value; + } + LocalDateTime offlineTime = LocalDateTime.parse(offlineTimeStr, FORMATTER); long elapsedMinutes = java.time.Duration.between(offlineTime, now).toMinutes(); - if (elapsedMinutes >= aliyunIotProperties.getOfflineWarnDelayMinutes()) { + // 根据设备类型选择对应的延迟时长 + int delayMinutes = (deviceType == SOLAR_CONTROLLER_TYPE) + ? aliyunIotProperties.getSolarOfflineWarnDelayMinutes() + : aliyunIotProperties.getOfflineWarnDelayMinutes(); + + if (elapsedMinutes >= delayMinutes) { // 提取 deviceName(去掉前缀) String deviceName = key.substring(OFFLINE_WAIT_KEY_PREFIX.length()); // 触发告警前先删除标记,防止重复触发 RedisUtils.deleteObject(key); - log.info("[离线告警] 设备离线已超过 {} 分钟,触发告警: {}", elapsedMinutes, deviceName); + log.info("[离线告警] 设备离线已超过 {} 分钟(阈值{}分钟),触发告警: {}", elapsedMinutes, delayMinutes, deviceName); deviceDataHandler.triggerOfflineAlarm(deviceName); } } catch (Exception e) {