定时清理,自动化修改、自动化误差上下温度改为0.5
parent
1d6d86b9d2
commit
ecb83531e8
|
|
@ -9,7 +9,7 @@ import java.math.BigDecimal;
|
||||||
*/
|
*/
|
||||||
public class TempJudgeUtil {
|
public class TempJudgeUtil {
|
||||||
// 条件参考温度允许的上下误差(抽成常量,后续可配置化)
|
// 条件参考温度允许的上下误差(抽成常量,后续可配置化)
|
||||||
public static final BigDecimal TEMP_ERROR_RANGE = java.math.BigDecimal.ONE;
|
public static final BigDecimal TEMP_ERROR_RANGE = BigDecimal.valueOf(0.5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 温度判断核心方法:根据当前温度与参考温度的差值,返回指令状态
|
* 温度判断核心方法:根据当前温度与参考温度的差值,返回指令状态
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ public class AgriStatusTask {
|
||||||
log.info("大棚表无数据,结束推送");
|
log.info("大棚表无数据,结束推送");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.info("从大棚表获取到合法IMEI总数:{}", imeiList.size());
|
|
||||||
|
|
||||||
// 3. 批量查询设备在线状态(Redis Pipeline,一次网络往返)
|
// 3. 批量查询设备在线状态(Redis Pipeline,一次网络往返)
|
||||||
agriStatusManager.asyncBatchPushMqtt(agriStatusManager.batchCheckDeviceOnline(imeiList));
|
agriStatusManager.asyncBatchPushMqtt(agriStatusManager.batchCheckDeviceOnline(imeiList));
|
||||||
|
|
@ -93,7 +92,6 @@ public class AgriStatusTask {
|
||||||
} finally {
|
} finally {
|
||||||
// 释放锁(可选,也可依赖TTL自动过期)
|
// 释放锁(可选,也可依赖TTL自动过期)
|
||||||
stringRedisTemplate.delete(LOCK_KEY);
|
stringRedisTemplate.delete(LOCK_KEY);
|
||||||
log.info("设备在线状态推送任务完成,耗时:{}ms", System.currentTimeMillis() - startTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,9 +146,6 @@ public class AgriStatusTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Lua查询完成:合法IMEI数={},在线数={}",
|
|
||||||
allGreenhouseImeiList.size(),
|
|
||||||
onlineStatusMap.values().stream().filter(Boolean::booleanValue).count());
|
|
||||||
return onlineStatusMap;
|
return onlineStatusMap;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Lua脚本执行失败", e);
|
log.error("Lua脚本执行失败", e);
|
||||||
|
|
|
||||||
|
|
@ -1,71 +1,50 @@
|
||||||
package com.agri.quartz.task;
|
package com.agri.quartz.task;
|
||||||
|
|
||||||
|
import com.agri.common.utils.spring.SpringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
import org.springframework.data.redis.core.Cursor;
|
import org.springframework.data.redis.core.Cursor;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.ScanOptions;
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* JDK 8 适配版 Redis 缓存清理任务
|
|
||||||
* 解决:1. RedisTemplate 多实例冲突 2. Cursor<byte[]> 类型不匹配 3. 空指针问题
|
|
||||||
* 功能:批量删除 Redis 中 sub: 开头的键
|
|
||||||
*/
|
|
||||||
@Component("agriTask")
|
@Component("agriTask")
|
||||||
public class AgriTask {
|
public class AgriTask {
|
||||||
|
|
||||||
// 核心修复:指定注入的 Bean 名称为 "redisTemplate"(匹配自定义配置的 Bean)
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate<String, String> redisTemplate;
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AgriTask.class);
|
private static final Logger log = LoggerFactory.getLogger(AgriTask.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* 每日零点执行:清理 sub: 开头的 Redis 键
|
|
||||||
*/
|
|
||||||
public void clearInvalidCache() {
|
public void clearInvalidCache() {
|
||||||
log.info("===== 开始执行Redis sub: 键清理任务 =====");
|
log.info("=============【定时任务】开始执行Redis sub: 键清理任务=============");
|
||||||
int deletedCount = 0;
|
int deletedCount = 0;
|
||||||
|
|
||||||
// 兜底获取 RedisTemplate(指定 Bean 名称,解决多实例冲突)
|
try {
|
||||||
|
// 重点*****
|
||||||
|
RedisTemplate<String, Object> redisTemplate = SpringUtils.getBean("redisTemplate");
|
||||||
if (redisTemplate == null) {
|
if (redisTemplate == null) {
|
||||||
log.error("RedisTemplate 初始化失败,清理任务终止");
|
log.error("RedisTemplate 获取失败,清理任务终止");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
// 配置 SCAN 参数:匹配 sub:*,分批遍历(每次1000条)
|
|
||||||
ScanOptions scanOptions = ScanOptions.scanOptions()
|
ScanOptions scanOptions = ScanOptions.scanOptions()
|
||||||
.match("sub:*")
|
.match("sub:*")
|
||||||
.count(1000)
|
.count(1000)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 接收 Cursor<byte[]> 类型(JDK 8 下原生返回类型)
|
|
||||||
Cursor<byte[]> cursor = redisTemplate.executeWithStickyConnection(connection ->
|
Cursor<byte[]> cursor = redisTemplate.executeWithStickyConnection(connection ->
|
||||||
connection.scan(scanOptions)
|
connection.scan(scanOptions)
|
||||||
);
|
);
|
||||||
|
|
||||||
// 批量删除缓冲区(存储 String 类型键)
|
|
||||||
List<String> batchKeys = new ArrayList<>(1000);
|
List<String> batchKeys = new ArrayList<>(1000);
|
||||||
|
|
||||||
// 遍历字节数组类型的键,转换为 String
|
|
||||||
while (cursor != null && cursor.hasNext()) {
|
while (cursor != null && cursor.hasNext()) {
|
||||||
byte[] keyBytes = cursor.next();
|
byte[] keyBytes = cursor.next();
|
||||||
// 转换 byte[] -> String(UTF-8 编码,避免乱码)
|
|
||||||
String key = new String(keyBytes, StandardCharsets.UTF_8);
|
String key = new String(keyBytes, StandardCharsets.UTF_8);
|
||||||
batchKeys.add(key);
|
batchKeys.add(key);
|
||||||
|
|
||||||
// 每攒1000个键批量删除
|
|
||||||
if (batchKeys.size() >= 1000) {
|
if (batchKeys.size() >= 1000) {
|
||||||
deletedCount += batchKeys.size();
|
deletedCount += batchKeys.size();
|
||||||
redisTemplate.delete(batchKeys);
|
redisTemplate.delete(batchKeys);
|
||||||
|
|
@ -74,14 +53,12 @@ public class AgriTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除剩余的键
|
|
||||||
if (!batchKeys.isEmpty()) {
|
if (!batchKeys.isEmpty()) {
|
||||||
deletedCount += batchKeys.size();
|
deletedCount += batchKeys.size();
|
||||||
redisTemplate.delete(batchKeys);
|
redisTemplate.delete(batchKeys);
|
||||||
log.info("批量删除剩余 {} 个sub: 键", batchKeys.size());
|
log.info("批量删除剩余 {} 个sub: 键", batchKeys.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭游标(避免资源泄漏)
|
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
try {
|
try {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
|
@ -90,11 +67,10 @@ public class AgriTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("===== Redis sub: 键清理完成,总计删除 {} 个键 =====", deletedCount);
|
log.info("=============【定时任务】Redis sub: 键清理完成,总计删除 {} 个键=============", deletedCount);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Redis sub: 键清理失败", e);
|
log.error("=============【定时任务】Redis sub: 键清理失败=============", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -370,7 +370,7 @@ public class RollerAutoTask {
|
||||||
// ========== 4. 计算运行时间并调度自动关 ==========
|
// ========== 4. 计算运行时间并调度自动关 ==========
|
||||||
int runTime = RollerTimeCalculator.calculateRunTime(len);
|
int runTime = RollerTimeCalculator.calculateRunTime(len);
|
||||||
if (runTime > 0) {
|
if (runTime > 0) {
|
||||||
String autoOffKey = roller + (isOpen ? "k" : "g");
|
String autoOffKey = roller + (isOpen ? "k1" : "g1");
|
||||||
autoOffManager.scheduleAutoOff(imei, autoOffKey, runTime);
|
autoOffManager.scheduleAutoOff(imei, autoOffKey, runTime);
|
||||||
log.debug("【自动关调度】设备{}卷膜「{}:{}」调度{}秒后自动关闭", imei, roller,(isOpen?"开":"关"), runTime);
|
log.debug("【自动关调度】设备{}卷膜「{}:{}」调度{}秒后自动关闭", imei, roller,(isOpen?"开":"关"), runTime);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,4 +142,19 @@ public class SysAgriInfoController extends BaseController
|
||||||
.update();
|
.update();
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改大棚名称
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('assets:agri:edit')")
|
||||||
|
@Log(title = "大棚管理", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping("/renameAgriName")
|
||||||
|
public AjaxResult renameAgriName(@RequestParam("imei") String imei, @RequestParam("newAgriName") String newAgriName)
|
||||||
|
{
|
||||||
|
boolean update = sysAgriInfoService.lambdaUpdate()
|
||||||
|
.eq(SysAgriInfo::getImei, imei)
|
||||||
|
.set(SysAgriInfo::getAgriName, newAgriName)
|
||||||
|
.update();
|
||||||
|
return update? success():error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue