This commit is contained in:
2026-07-14 12:43:23 +08:00
parent 8f7a35e3c7
commit 29ecbf321f
52 changed files with 1197 additions and 324 deletions

View File

@@ -1,41 +1,5 @@
package com.maibu.service;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson2.JSON;
import com.maibu.common.CommandConstant;
import com.maibu.common.NettyCacheKey;
import com.maibu.core.business.DeviceRunningStatusHistory;
import com.maibu.core.business.DeviceStatusRecordDTO;
import com.maibu.core.enums.CompareEnum;
import com.maibu.core.enums.ErrorSource;
import com.maibu.core.enums.RespondCode;
import com.maibu.core.redis.RedisCache;
import com.maibu.dto.DeviceErrorPushDTO;
import com.maibu.dto.DeviceErrorPushDetail;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.business.inter.WebsocketMesDispather;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.core.business.alarm_center.AlarmMessage;
import com.maibu.manager.DeviceSessionManager;
import com.maibu.mapper.ErrorIdentificationStandardMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
import com.maibu.mqtt.MqttTopic;
import com.maibu.utils.CommandUtils;
import com.maibu.utils.CompareUtils;
import com.maibu.utils.json.JsonUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
@@ -44,9 +8,44 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.maibu.common.NettyCacheKey;
import com.maibu.core.business.DeviceRunningStatusHistory;
import com.maibu.core.business.DeviceStatusRecordDTO;
import com.maibu.core.business.ErrorIdentificationStandard;
import com.maibu.core.business.alarm_center.AlarmMessage;
import com.maibu.core.business.device.NettyDevice;
import com.maibu.core.business.inter.WebsocketMesDispather;
import com.maibu.core.enums.CompareEnum;
import com.maibu.core.enums.ErrorSource;
import com.maibu.core.enums.RespondCode;
import com.maibu.core.redis.RedisCache;
import com.maibu.dto.DeviceErrorPushDTO;
import com.maibu.manager.DeviceSessionManager;
import com.maibu.mapper.ErrorIdentificationStandardMapper;
import com.maibu.memory.GlobalMemory;
import com.maibu.memory.SiteMemory;
import com.maibu.mqtt.MqttTopic;
import com.maibu.utils.CompareUtils;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
@@ -55,9 +54,6 @@ public class DeviceThreadService {
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private SiteMemory siteMemory;
@Autowired
private RedisCache redisCache;
@@ -76,6 +72,9 @@ public class DeviceThreadService {
public void deviceErrorMonitor() throws InterruptedException, IOException {
initStandard();
// TODO fix 后续是否分多个线程 一个site一个线程
// 有还需要更新接受故障方式。
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleWithFixedDelay(() -> {
try {
@@ -89,11 +88,16 @@ public class DeviceThreadService {
recordDTO.getHistories()
.sort(Comparator.comparing(DeviceRunningStatusHistory::getCreateTime).reversed());
DeviceRunningStatusHistory history = recordDTO.getHistories().get(0);
List<AlarmMessage> compared = compareErrorStandard(history,
siteMemory.standards.get(ErrorSource.MOWER));
String[] parts = k.split(":");
String deviceId = parts[1];
NettyDevice slaveDevice = sessionManager.getDevice(deviceId);
Long siteId = slaveDevice != null ? slaveDevice.getDevice().getSiteId() : null;
Long orgId = slaveDevice != null ? slaveDevice.getDevice().getOrgId() : null;
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
List<AlarmMessage> compared = compareErrorStandard(siteId, orgId, history,
siteMemory.standards.get(ErrorSource.MOWER));
DeviceErrorPushDTO pushDTO = new DeviceErrorPushDTO();
pushDTO.setDeviceId(deviceId);
@@ -116,30 +120,55 @@ public class DeviceThreadService {
} catch (Exception e) {
log.error("执行监测错误线程错误:{}", e.getMessage());
}
}, 0, 2, TimeUnit.MINUTES);
}, 0, 5, TimeUnit.SECONDS);
}
public void initStandard() throws IOException {
if (siteMemory.standards == null) {
List<ErrorIdentificationStandard> list = standardMapper.selectList();
if (CollectionUtils.isEmpty(list)) {
// 读取resource目录下的device-config.json文件
Resource resource = resourceLoader.getResource("classpath:errorStandard.json");
// 使用fastjson2转换为DeviceConfig对象
String jsonContent = IoUtil.readUtf8(resource.getInputStream());
List<ErrorIdentificationStandard> newStandards = JSON.parseArray(jsonContent,
ErrorIdentificationStandard.class);
if (!CollectionUtils.isEmpty(newStandards)) {
standardMapper.insertBatch(newStandards);
siteMemory.standards = newStandards.stream()
.collect(java.util.stream.Collectors
.groupingBy(ErrorIdentificationStandard::getErrorSource));
GlobalMemory.getAllSiteMemory().forEach(siteMemory -> {
if (siteMemory != null && siteMemory.standards == null) {
LambdaQueryWrapper<ErrorIdentificationStandard> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ErrorIdentificationStandard::getSiteId, siteMemory.sysSite.getId());
List<ErrorIdentificationStandard> list = standardMapper.selectList(queryWrapper);
if (CollectionUtils.isEmpty(list)) {
try {
// 读取resource目录下的device-config.json文件
Resource resource = resourceLoader.getResource("classpath:errorStandard.json");
// 使用fastjson2转换为DeviceConfig对象
String jsonContent;
jsonContent = IoUtil.readUtf8(resource.getInputStream());
List<ErrorIdentificationStandard> newStandards = JSON.parseArray(jsonContent,
ErrorIdentificationStandard.class);
if (!CollectionUtils.isEmpty(newStandards)) {
newStandards.forEach(x -> {
x.setOrgId(siteMemory.sysSite.getOrgId());
x.setSiteId(siteMemory.sysSite.getId());
});
standardMapper.insertBatch(newStandards);
siteMemory.standards = newStandards.stream()
.filter(e -> e.getErrorSource() != null)
.collect(Collectors.groupingBy(
ErrorIdentificationStandard::getErrorSource,
ConcurrentHashMap::new,
Collectors.toList()));
}
} catch (IORuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
siteMemory.standards = list.stream()
.filter(e -> e.getErrorSource() != null)
.collect(Collectors.groupingBy(
ErrorIdentificationStandard::getErrorSource,
ConcurrentHashMap::new,
Collectors.toList()));
}
} else {
siteMemory.standards = list.stream()
.collect(java.util.stream.Collectors.groupingBy(ErrorIdentificationStandard::getErrorSource));
}
}
});
}
public void pushErrorMessage(String deviceId, String dto) {
@@ -165,7 +194,7 @@ public class DeviceThreadService {
}
}
public List<AlarmMessage> compareErrorStandard(DeviceRunningStatusHistory history,
public List<AlarmMessage> compareErrorStandard(Long siteId, Long orgId, DeviceRunningStatusHistory history,
List<ErrorIdentificationStandard> standards) {
if (history == null || CollectionUtils.isEmpty(standards))
return null;
@@ -189,6 +218,8 @@ public class DeviceThreadService {
alarm.setSuggestion(standard.getSuggestion());
alarm.setStatus("未处理");
alarm.setTime(LocalDateTime.now());
alarm.setOrgId(orgId);
alarm.setSiteId(siteId);
list.add(alarm);
}
}