获取所有设备最新的温湿度数据

master
lld 2026-03-31 16:50:29 +08:00
parent af3be1f431
commit c35551698c
3 changed files with 109 additions and 8 deletions

View File

@ -39,7 +39,7 @@ public class AgriStatusTask {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Value("${spring.mqtt.dtu-ctl-lock-ttl:15}")
@Value("${spring.mqtt.dtu-ctl-lock-ttl:60}")
private int lockTtl;
@Autowired
@ -70,12 +70,7 @@ public class AgriStatusTask {
}
long startTime = System.currentTimeMillis();
try {
// 2. 安全遍历所有 sub: 开头的 key提取设备 IMEI
// List<String> allDeviceImeiList = scanAllSubDeviceImei();
// if (allDeviceImeiList.isEmpty()) {
// log.info("没有找到任何设备订阅记录,结束任务");
// return;
// }
// 查询大棚列表所有在线设备
List<String> imeiList = agriInfoService.queryImeiByUserId(null);
if (imeiList.isEmpty()) {

View File

@ -0,0 +1,106 @@
package com.agri.quartz.task;
import com.agri.framework.config.MqttConfig;
import com.agri.system.service.ISysAgriInfoService;
import com.agri.system.service.ISysDtuDataService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* // 1、查询大棚所有imei
* // 2、查询所有设备最新的温湿度数据
* // 3、判断谁不存在
* // 4、发送不存在的告警
*/
@Component
public class AgriTempTask {
private static final Logger log = LoggerFactory.getLogger(AgriTempTask.class);
@Autowired
private ISysDtuDataService dtuDataService;
@Autowired
private ISysAgriInfoService agriInfoService;
private static final String LOCK_KEY = "lock:check:temp:push";
@Resource
private StringRedisTemplate stringRedisTemplate;
@Value("${spring.mqtt.dtu-ctl-lock-ttl:60}")
private int lockTtl;
@Resource
private MqttConfig.MqttMessageSender mqttMessageSender;
private final ObjectMapper objectMapper = new ObjectMapper();
public void checkTempStatus() {
Boolean lockSuccess = stringRedisTemplate.opsForValue()
.setIfAbsent(LOCK_KEY, "agriTempTask", lockTtl, TimeUnit.SECONDS);
// 补充处理Redis连接异常的情况
if (lockSuccess == null) {
log.error("获取分布式锁失败Redis连接异常");
return;
}
if (!lockSuccess) {
log.debug("其他节点正在执行,跳过本次推送");
return;
}
try {
// 查询大棚所有imei
List<String> imeiList = agriInfoService.queryImeiByUserId(null);
if (imeiList.isEmpty()) {
log.info("大棚表无数据,结束推送");
return;
}
// 查询所有设备最新的温湿度数据
List<Map<String, Object>> dtuDataList = dtuDataService.getLastDtuDataByImeiList(imeiList);
if (CollectionUtils.isEmpty(dtuDataList)) return;
// 判断谁不存在
ArrayList<String> offlineTempList = new ArrayList<>();
for (String imei : imeiList) {
if (dtuDataList.stream().noneMatch(item -> item.get("imei").equals(imei))) {
offlineTempList.add(imei);
log.info("设备{} 不存在温湿度数据", imei);
}
}
// 不存在的告警
for (String imei : offlineTempList) {
// todo 设备离线推送 发消息提醒
Map<String, Object> alarmMsg = new HashMap<>();
alarmMsg.put("online", "温度离线");
alarmMsg.put("time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
alarmMsg.put("imei", imei);
String alarmMessage = objectMapper.writeValueAsString(alarmMsg);
mqttMessageSender.publish("frontend/" + imei + "/alarm", alarmMessage);
}
} catch (Exception e) {
log.error("设备在线状态推送任务异常", e);
// 可选:异常告警(如企业微信/钉钉)
// WxUtil.pushText("【设备在线状态推送异常】\n" + e.getMessage());
} finally {
// 释放锁可选也可依赖TTL自动过期
stringRedisTemplate.delete(LOCK_KEY);
}
}
}

View File

@ -148,7 +148,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<foreach collection="imeiList" item="imei" open="(" separator="," close=")">
#{imei}
</foreach>
AND time >= DATE_SUB(NOW(), INTERVAL 1 MINUTE)
AND time >= DATE_SUB(NOW(), INTERVAL 90 SECOND)
GROUP BY imei
)
</select>