|
@@ -20,9 +20,7 @@ import vip.xiaonuo.common.cache.CommonCacheOperator;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Objects;
|
|
|
-import java.util.Set;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -67,52 +65,112 @@ public class DeviceOfflineDetectionService {
|
|
|
* 定期检测设备状态是否离线
|
|
|
* 每 5 分钟运行一次
|
|
|
*/
|
|
|
- @Scheduled(fixedRate = 300000) // 每 5 分钟(以毫秒为单位)
|
|
|
-// @Scheduled(fixedRateString = "${coldchain.device-offline-interval:300000}")
|
|
|
+// @Scheduled(fixedRate = 300000) // 每 5 分钟(以毫秒为单位)
|
|
|
+//// @Scheduled(fixedRateString = "${coldchain.device-offline-interval:300000}")
|
|
|
+// public void checkDeviceStatus() {
|
|
|
+// log.info("开始自动检测设备在线状态...");
|
|
|
+// // 获取 Redis 中所有设备的键
|
|
|
+// Set<String> deviceKeys = getAllDeviceCodes();
|
|
|
+// Map<String,Integer> deviceCodes = new LinkedHashMap<>();
|
|
|
+// if(deviceKeys!=null && !deviceKeys.isEmpty()){
|
|
|
+// // 遍历设备键,逐一检测状态
|
|
|
+// for (String key : deviceKeys) {
|
|
|
+// String[] split = key.split(KEY_SPILT);
|
|
|
+// if (split.length == 0) {
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+// String deviceCode = split[0];
|
|
|
+// Integer route = null;
|
|
|
+// if (split.length == 2) {
|
|
|
+// route = Integer.valueOf(split[1]);
|
|
|
+// }
|
|
|
+// deviceCodes.put(deviceCode,route);
|
|
|
+// // 从 Redis 中获取设备的最后上报时间
|
|
|
+// String lastReportTimeStr = getLastDeviceTime(getKey(deviceCode, route));
|
|
|
+// if (lastReportTimeStr != null) {
|
|
|
+// // 将上报时间字符串解析为 LocalDateTime 对象
|
|
|
+// LocalDateTime lastReportTime = LocalDateTime.parse(lastReportTimeStr, DATE_TIME_FORMATTER);
|
|
|
+// // 获取当前时间
|
|
|
+// LocalDateTime now = LocalDateTime.now();
|
|
|
+// final long OFFLINE_THRESHOLD_MINUTES = jfcloudColdChainServerProperties.getDeviceOfflineInterval() / 60 / 1000;
|
|
|
+// // 如果最后上报时间超过离线阈值,判断设备为离线
|
|
|
+// if (lastReportTime.plusMinutes(OFFLINE_THRESHOLD_MINUTES).isBefore(now)) {
|
|
|
+// log.error("设备{}-{} 已离线,最后上报时间:{}。\n", deviceCode, route, lastReportTimeStr);
|
|
|
+// publishAlarm(deviceCode, route, lastReportTimeStr);
|
|
|
+// monitorTargetService.updateStatusByDeviceCode(deviceCode, route, MonitorStatusEnum.OFF);
|
|
|
+// } else {
|
|
|
+// log.info("设备 {}-{} 在线,最后上报时间:{}。\n", deviceCode, route, lastReportTimeStr);
|
|
|
+// monitorTargetService.updateStatusByDeviceCode(deviceCode, route, MonitorStatusEnum.ONLINE);
|
|
|
+// }
|
|
|
+// } else {
|
|
|
+// monitorTargetService.updateStatusByDeviceCode(deviceCode, route, MonitorStatusEnum.OFF);
|
|
|
+// log.info("设备 {}-{} 缺少数据,可能从未上报过。\n", deviceCode, route);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// log.info("查找出从来没上线的设备都统一都下线处理");
|
|
|
+// monitorTargetService.updateStatusbatch(deviceCodes);
|
|
|
+// }
|
|
|
+ @Scheduled(fixedRate = 300000) // 每 5 分钟运行一次
|
|
|
public void checkDeviceStatus() {
|
|
|
- log.info("开始检测离线设备状态...");
|
|
|
- // 获取 Redis 中所有设备的键
|
|
|
+ log.info("开始自动检测设备在线状态...");
|
|
|
+ Map<String, Integer> deviceCodes = new LinkedHashMap<>();
|
|
|
Set<String> deviceKeys = getAllDeviceCodes();
|
|
|
- if (deviceKeys == null || deviceKeys.isEmpty()) {
|
|
|
- log.info("没有需要检测的设备。");
|
|
|
+ if(deviceKeys!=null && deviceKeys.size()>0){
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ final long OFFLINE_THRESHOLD_MINUTES = jfcloudColdChainServerProperties.getDeviceOfflineInterval() / 60 / 1000;
|
|
|
+ for (String key : deviceKeys) {
|
|
|
+ processDevice(key, now, OFFLINE_THRESHOLD_MINUTES, deviceCodes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info("查找出从来没上线的设备,统一设置为离线...");
|
|
|
+ monitorTargetService.updateStatusbatch(deviceCodes);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理设备状态
|
|
|
+ * @param key
|
|
|
+ * @param now
|
|
|
+ * @param offlineThresholdMinutes
|
|
|
+ * @param deviceCodes
|
|
|
+ */
|
|
|
+ private void processDevice(String key, LocalDateTime now, long offlineThresholdMinutes, Map<String, Integer> deviceCodes) {
|
|
|
+ String[] split = key.split(KEY_SPILT);
|
|
|
+ if (split.length == 0) {
|
|
|
return;
|
|
|
}
|
|
|
- // 遍历设备键,逐一检测状态
|
|
|
- for (String key : deviceKeys) {
|
|
|
- String[] split = key.split(KEY_SPILT);
|
|
|
- if (split.length == 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- String deviceCode = split[0];
|
|
|
- Integer route = null;
|
|
|
+ String deviceCode = split[0];
|
|
|
+ Integer route = null;
|
|
|
+ try {
|
|
|
if (split.length == 2) {
|
|
|
route = Integer.valueOf(split[1]);
|
|
|
}
|
|
|
- // 从 Redis 中获取设备的最后上报时间
|
|
|
- String lastReportTimeStr = getLastDeviceTime(getKey(deviceCode, route));
|
|
|
- if (lastReportTimeStr != null) {
|
|
|
- // 将上报时间字符串解析为 LocalDateTime 对象
|
|
|
- LocalDateTime lastReportTime = LocalDateTime.parse(lastReportTimeStr, DATE_TIME_FORMATTER);
|
|
|
- // 获取当前时间
|
|
|
- LocalDateTime now = LocalDateTime.now();
|
|
|
- final long OFFLINE_THRESHOLD_MINUTES = jfcloudColdChainServerProperties.getDeviceOfflineInterval() / 60 / 1000;
|
|
|
- // 如果最后上报时间超过离线阈值,判断设备为离线
|
|
|
- if (lastReportTime.plusMinutes(OFFLINE_THRESHOLD_MINUTES).isBefore(now)) {
|
|
|
- log.error("设备{}-{} 已离线,最后上报时间:{}。\n", deviceCode, route, lastReportTimeStr);
|
|
|
- publishAlarm(deviceCode, route, lastReportTimeStr);
|
|
|
- monitorTargetService.updateStatusByDeviceCode(deviceCode, route, MonitorStatusEnum.OFF);
|
|
|
- } else {
|
|
|
- log.info("设备 {}-{} 在线,最后上报时间:{}。\n", deviceCode, route, lastReportTimeStr);
|
|
|
- monitorTargetService.updateStatusByDeviceCode(deviceCode, route, MonitorStatusEnum.ONLINE);
|
|
|
- }
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.error("设备键 {} 中的 route 数据格式错误,跳过处理。", key, e);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ deviceCodes.put(deviceCode, route);
|
|
|
+ String lastReportTimeStr = getLastDeviceTime(getKey(deviceCode, route));
|
|
|
+ MonitorStatusEnum status;
|
|
|
+ if (lastReportTimeStr != null) {
|
|
|
+ LocalDateTime lastReportTime = LocalDateTime.parse(lastReportTimeStr, DATE_TIME_FORMATTER);
|
|
|
+ if (lastReportTime.plusMinutes(offlineThresholdMinutes).isBefore(now)) {
|
|
|
+ status = MonitorStatusEnum.OFF;
|
|
|
+ log.warn("设备 {}-{} 已离线,最后上报时间:{}。", deviceCode, route, lastReportTimeStr);
|
|
|
+ publishAlarm(deviceCode, route, lastReportTimeStr);
|
|
|
} else {
|
|
|
- monitorTargetService.updateStatusByDeviceCode(deviceCode, route, MonitorStatusEnum.OFF);
|
|
|
- log.info("设备 {}-{} 缺少数据,可能从未上报过。\n", deviceCode, route);
|
|
|
+ status = MonitorStatusEnum.ONLINE;
|
|
|
+ log.debug("设备 {}-{} 在线,最后上报时间:{}。", deviceCode, route, lastReportTimeStr);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ status = MonitorStatusEnum.OFF;
|
|
|
+ log.info("设备 {}-{} 缺少数据,可能从未上报过。", deviceCode, route);
|
|
|
}
|
|
|
+ monitorTargetService.updateStatusByDeviceCode(deviceCode, route, status);
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
private void publishAlarm(String deviceCode, Integer route, String time) {
|
|
|
MonitorTargetRegion monitorTargetRegion = monitorTargetRegionService.findOneByDeviceCodeAndSensorNo(deviceCode, route);
|
|
|
if (Objects.isNull(monitorTargetRegion)) {
|