fix: 新增定时任务,饱和度。
This commit is contained in:
@@ -0,0 +1,80 @@
|
|||||||
|
package com.intc.iot.task;
|
||||||
|
|
||||||
|
import com.intc.common.redis.utils.RedisUtils;
|
||||||
|
import com.intc.iot.config.AliyunIotProperties;
|
||||||
|
import com.intc.iot.handler.DeviceDataHandler;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 夜间溶解氧饱和度持续超阈告警延迟触发定时任务
|
||||||
|
* 对应 C# UpdateDataSecondlyJob.CheckWarnAndNotice 中对 SaturaHigh WarnWait 的处理:
|
||||||
|
* 夜间(20:00-08:00)饱和度 >= 200% 持续超过配置的 saturability-warn-hours 小时才真正触发告警。
|
||||||
|
*
|
||||||
|
* @author intc-iot
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@ConditionalOnBean(DeviceDataHandler.class)
|
||||||
|
public class DeviceSaturaHighWarnTask {
|
||||||
|
|
||||||
|
private static final String SATURA_WAIT_KEY_PREFIX = "device:satura:wait:";
|
||||||
|
|
||||||
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
private final DeviceDataHandler deviceDataHandler;
|
||||||
|
|
||||||
|
private final AliyunIotProperties aliyunIotProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每分钟扫描一次饱和度超阈等待标记
|
||||||
|
* 对超过配置的 saturability-warn-hours 小时的设备触发告警
|
||||||
|
*/
|
||||||
|
@Scheduled(fixedDelay = 60000)
|
||||||
|
public void checkSaturaWaitAndTrigger() {
|
||||||
|
try {
|
||||||
|
Collection<String> keys = RedisUtils.keys(SATURA_WAIT_KEY_PREFIX + "*");
|
||||||
|
if (keys == null || keys.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
int warnHours = aliyunIotProperties.getSaturabilityWarnHours();
|
||||||
|
|
||||||
|
for (String key : keys) {
|
||||||
|
try {
|
||||||
|
String firstExceedTimeStr = RedisUtils.getCacheObject(key);
|
||||||
|
if (firstExceedTimeStr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDateTime firstExceedTime = LocalDateTime.parse(firstExceedTimeStr, FORMATTER);
|
||||||
|
long elapsedHours = java.time.Duration.between(firstExceedTime, now).toHours();
|
||||||
|
|
||||||
|
if (elapsedHours >= warnHours) {
|
||||||
|
// 提取 deviceName(去掉前缀)
|
||||||
|
String deviceName = key.substring(SATURA_WAIT_KEY_PREFIX.length());
|
||||||
|
|
||||||
|
// 触发告警前先删除标记,防止重复触发
|
||||||
|
RedisUtils.deleteObject(key);
|
||||||
|
|
||||||
|
log.info("[饱和度告警] 设备夜间饱和度持续超阈已达 {} 小时,触发告警: {}", elapsedHours, deviceName);
|
||||||
|
deviceDataHandler.triggerSaturaHighAlarm(deviceName);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[饱和度告警] 处理单条等待标记异常,key={}: {}", key, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[饱和度告警] 扫描等待标记异常: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user