获取所有设备最新的温湿度数据
parent
af3be1f431
commit
c35551698c
|
|
@ -39,7 +39,7 @@ public class AgriStatusTask {
|
||||||
@Resource
|
@Resource
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
@Value("${spring.mqtt.dtu-ctl-lock-ttl:15}")
|
@Value("${spring.mqtt.dtu-ctl-lock-ttl:60}")
|
||||||
private int lockTtl;
|
private int lockTtl;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
@ -70,12 +70,7 @@ public class AgriStatusTask {
|
||||||
}
|
}
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
// 2. 安全遍历所有 sub: 开头的 key,提取设备 IMEI
|
|
||||||
// List<String> allDeviceImeiList = scanAllSubDeviceImei();
|
|
||||||
// if (allDeviceImeiList.isEmpty()) {
|
|
||||||
// log.info("没有找到任何设备订阅记录,结束任务");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// 查询大棚列表所有在线设备
|
// 查询大棚列表所有在线设备
|
||||||
List<String> imeiList = agriInfoService.queryImeiByUserId(null);
|
List<String> imeiList = agriInfoService.queryImeiByUserId(null);
|
||||||
if (imeiList.isEmpty()) {
|
if (imeiList.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<foreach collection="imeiList" item="imei" open="(" separator="," close=")">
|
<foreach collection="imeiList" item="imei" open="(" separator="," close=")">
|
||||||
#{imei}
|
#{imei}
|
||||||
</foreach>
|
</foreach>
|
||||||
AND time >= DATE_SUB(NOW(), INTERVAL 1 MINUTE)
|
AND time >= DATE_SUB(NOW(), INTERVAL 90 SECOND)
|
||||||
GROUP BY imei
|
GROUP BY imei
|
||||||
)
|
)
|
||||||
</select>
|
</select>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue