From 69bc7bf0200295539e3adcf4cec3ff111b0b6c96 Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Mon, 27 Apr 2026 16:48:21 +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=E8=AE=BE=E5=A4=87=E4=BC=91=E7=9C=A0=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E4=BF=AE=E6=94=B9=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constant/DefineDeviceWarnCode.java | 10 ++++++ .../fishery/controller/PondController.java | 2 +- .../intc/iot/handler/DeviceDataHandler.java | 33 +++++++++++++++---- .../intc/iot/task/DeviceOfflineWarnTask.java | 7 ++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/constant/DefineDeviceWarnCode.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/constant/DefineDeviceWarnCode.java index 99e8b35..287776a 100644 --- a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/constant/DefineDeviceWarnCode.java +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/constant/DefineDeviceWarnCode.java @@ -66,6 +66,13 @@ public class DefineDeviceWarnCode { */ public static final int SaturaHigh = 1 << 10; + /** + * 设备休眠(太阳能网控专用) 1 << 11 = 2048 + * 太阳能网控设备正常工作周期为 在线2分钟+休眠8分钟, + * 休眠期间 IoT 平台上报离线,但属于正常行为,不等同于真正离线。 + */ + public static final int DeviceSleeping = 1 << 11; + /** * 设备断电(控制器) 1 << 15 = 32768 */ @@ -103,6 +110,9 @@ public class DefineDeviceWarnCode { if ((warnCode & DeviceOffline) != 0) { return "设备离线"; } + if ((warnCode & DeviceSleeping) != 0) { + return "设备休眠"; + } if ((warnCode & ErrorPowerOff) != 0) { return "设备断电"; } diff --git a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/PondController.java b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/PondController.java index 5d5ddeb..37f8007 100644 --- a/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/PondController.java +++ b/intc-modules/intc-fishery/src/main/java/com/intc/fishery/controller/PondController.java @@ -809,7 +809,7 @@ public class PondController extends BaseController { warnCode |= device.getWarnCode(); } - // 判断设备是否在线(简化判断,实际应根据业务逻辑) + // 判断设备是否在线(DeviceSleeping 不算离线,太阳能网控休眠属于正常工作) if (device.getWarnCode() == null || ((device.getWarnCode() & DefineDeviceWarnCode.DeviceTimeDead) == 0 && (device.getWarnCode() & DefineDeviceWarnCode.DeviceOffline) == 0)) { 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 abd96e2..c30aff9 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 @@ -916,8 +916,14 @@ public class DeviceDataHandler { RedisUtils.setCacheObject(redisKey, redisValue, Duration.ofMinutes(ttlMinutes)); log.info("[离线告警] 设备离线,已记录等待标记,将在 {} 分钟后触发告警: {}", offlineDelayMinutes, deviceName); - // 同步更新 Device.warnCode,写入离线标志位 - setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceOffline, true); + // 同步更新 Device.warnCode + // 太阳能网控(type=3)正常休眠周期为在线2分钟+休眠8分钟,置 DeviceSleeping 位表示休眠; + // 其他设备立即置 DeviceOffline 位 + if (deviceTypeForRedis == 3) { + setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceSleeping, true); + } else { + setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceOffline, true); + } } /** @@ -933,8 +939,20 @@ public class DeviceDataHandler { log.info("[离线告警] 设备已上线,取消离线告警: {}", deviceName); } - // 同步更新 Device.warnCode,清除离线标志位 + // 同步更新 Device.warnCode,清除离线和休眠标志位 setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceOffline, false); + setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceSleeping, false); + } + + /** + * 太阳能网控设备离线超时:从休眠状态转为真正离线 + * 置 DeviceOffline 位,清 DeviceSleeping 位 + * + * @param deviceName 设备名称(serialNum) + */ + public void setDeviceOfflineAndClearSleeping(String deviceName) { + setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceSleeping, false); + setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceOffline, true); } /** @@ -1943,13 +1961,14 @@ public class DeviceDataHandler { if (device == null || device.getWarnCode() == null) { return; } - // 只有当前有离线标志时才更新,避免无意义的 SQL - if ((device.getWarnCode() & DefineDeviceWarnCode.DeviceOffline) != 0) { + // 只有当前有离线或休眠标志时才更新,避免无意义的 SQL + int offlineSleepingMask = DefineDeviceWarnCode.DeviceOffline | DefineDeviceWarnCode.DeviceSleeping; + if ((device.getWarnCode() & offlineSleepingMask) != 0) { Device update = new Device(); update.setId(device.getId()); - update.setWarnCode(device.getWarnCode() & ~DefineDeviceWarnCode.DeviceOffline); + update.setWarnCode(device.getWarnCode() & ~offlineSleepingMask); deviceMapper.updateById(update); - log.debug("[在线] 已清除设备数据库离线标志: {}", deviceName); + log.debug("[在线] 已清除设备数据库离线/休眠标志: {}", deviceName); } } catch (Exception e) { log.error("[在线] 清除设备离线标志失败[{}]: {}", deviceName, e.getMessage()); 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 070fbca..c1a0c8f 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 @@ -1,6 +1,7 @@ package com.intc.iot.task; import com.intc.common.redis.utils.RedisUtils; +import com.intc.fishery.constant.DefineDeviceWarnCode; import com.intc.iot.config.AliyunIotProperties; import com.intc.iot.handler.DeviceDataHandler; import lombok.RequiredArgsConstructor; @@ -92,6 +93,12 @@ public class DeviceOfflineWarnTask { RedisUtils.deleteObject(key); log.info("[离线告警] 设备离线已超过 {} 分钟(阈值{}分钟),触发告警: {}", elapsedMinutes, delayMinutes, deviceName); + + // 太阳能网控设备超时后,从休眠状态转为真正离线:置 DeviceOffline 位,清 DeviceSleeping 位 + if (deviceType == SOLAR_CONTROLLER_TYPE) { + deviceDataHandler.setDeviceOfflineAndClearSleeping(deviceName); + } + deviceDataHandler.triggerOfflineAlarm(deviceName); } } catch (Exception e) {