2026-04-17 17:12:41 +08:00
|
|
|
|
package com.maibu.service;
|
2026-04-17 10:42:16 +08:00
|
|
|
|
|
2026-09-09 09:01:54 +08:00
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
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.ScheduledExecutorService;
|
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
import org.springframework.core.io.Resource;
|
|
|
|
|
|
import org.springframework.core.io.ResourceLoader;
|
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
|
2026-04-17 10:42:16 +08:00
|
|
|
|
import com.alibaba.fastjson2.JSON;
|
2026-07-14 12:43:23 +08:00
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
2026-08-25 09:19:12 +08:00
|
|
|
|
import com.maibu.constant.Constant;
|
2026-09-09 09:01:54 +08:00
|
|
|
|
import com.maibu.constant.NettyCacheKey;
|
2026-08-25 09:19:12 +08:00
|
|
|
|
import com.maibu.core.business.Device;
|
2026-04-30 15:25:58 +08:00
|
|
|
|
import com.maibu.core.business.DeviceRunningStatusHistory;
|
|
|
|
|
|
import com.maibu.core.business.DeviceStatusRecordDTO;
|
2026-07-14 12:43:23 +08:00
|
|
|
|
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;
|
2026-09-09 09:01:54 +08:00
|
|
|
|
import com.maibu.core.enums.CompareEnum;
|
|
|
|
|
|
import com.maibu.core.enums.ConnectorStatus;
|
|
|
|
|
|
import com.maibu.core.enums.DeviceStatus;
|
|
|
|
|
|
import com.maibu.core.enums.ErrorSource;
|
|
|
|
|
|
import com.maibu.core.enums.RespondCode;
|
2026-08-25 09:19:12 +08:00
|
|
|
|
import com.maibu.core.host.HeartBeatDTO;
|
2026-09-09 09:01:54 +08:00
|
|
|
|
import com.maibu.core.host.LocationMessage;
|
2026-04-17 17:12:41 +08:00
|
|
|
|
import com.maibu.core.redis.RedisCache;
|
|
|
|
|
|
import com.maibu.dto.DeviceErrorPushDTO;
|
|
|
|
|
|
import com.maibu.mapper.ErrorIdentificationStandardMapper;
|
2026-09-09 09:01:54 +08:00
|
|
|
|
import com.maibu.mapper.HostLocationMapper;
|
2026-08-25 09:19:12 +08:00
|
|
|
|
import com.maibu.memory.DeviceSessionManager;
|
2026-07-09 08:40:32 +08:00
|
|
|
|
import com.maibu.memory.GlobalMemory;
|
2026-04-30 15:25:58 +08:00
|
|
|
|
import com.maibu.memory.SiteMemory;
|
2026-07-09 08:40:32 +08:00
|
|
|
|
import com.maibu.mqtt.MqttTopic;
|
2026-04-17 17:12:41 +08:00
|
|
|
|
import com.maibu.utils.CompareUtils;
|
2026-08-25 09:19:12 +08:00
|
|
|
|
|
2026-09-09 09:01:54 +08:00
|
|
|
|
import cn.hutool.core.io.IORuntimeException;
|
|
|
|
|
|
import cn.hutool.core.io.IoUtil;
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
2026-04-17 10:42:16 +08:00
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
|
@Service
|
|
|
|
|
|
public class DeviceThreadService {
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private ResourceLoader resourceLoader;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private RedisCache redisCache;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private DeviceSessionManager sessionManager;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private ErrorIdentificationStandardMapper standardMapper;
|
|
|
|
|
|
|
2026-07-09 08:40:32 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private WebsocketMesDispather websocketMesDispather;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private AlertPushService alertPushService;
|
2026-04-17 10:42:16 +08:00
|
|
|
|
|
2026-08-19 16:57:55 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private IDeviceService deviceService;
|
|
|
|
|
|
|
2026-08-07 08:45:43 +08:00
|
|
|
|
@Value("${mqtt.client-id}")
|
|
|
|
|
|
private String mqttClientId;
|
|
|
|
|
|
|
2026-08-25 09:19:12 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private ScheduledExecutorService executor;
|
|
|
|
|
|
|
2026-09-09 09:01:54 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private HostLocationMapper hostLocationMapper;
|
|
|
|
|
|
|
2026-04-17 10:42:16 +08:00
|
|
|
|
public void deviceErrorMonitor() throws InterruptedException, IOException {
|
|
|
|
|
|
initStandard();
|
|
|
|
|
|
|
2026-09-09 09:01:54 +08:00
|
|
|
|
// TODO fix 后续是否分多个线程 一个site一个线程
|
2026-07-14 12:43:23 +08:00
|
|
|
|
// 有还需要更新接受故障方式。
|
2026-04-17 10:42:16 +08:00
|
|
|
|
executor.scheduleWithFixedDelay(() -> {
|
|
|
|
|
|
try {
|
|
|
|
|
|
String key = NettyCacheKey.deviceRunningStatusKey;
|
|
|
|
|
|
Collection<String> keys = redisCache.getListKeyByPrefix(key);
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(keys)) {
|
2026-07-09 08:40:32 +08:00
|
|
|
|
List<DeviceErrorPushDTO> pushList = new ArrayList<>();
|
2026-04-17 10:42:16 +08:00
|
|
|
|
keys.forEach(k -> {
|
|
|
|
|
|
DeviceStatusRecordDTO recordDTO = redisCache.getCacheObject(k);
|
|
|
|
|
|
if (recordDTO != null && !CollectionUtils.isEmpty(recordDTO.getHistories())) {
|
2026-07-09 08:40:32 +08:00
|
|
|
|
recordDTO.getHistories()
|
|
|
|
|
|
.sort(Comparator.comparing(DeviceRunningStatusHistory::getCreateTime).reversed());
|
2026-04-17 10:42:16 +08:00
|
|
|
|
DeviceRunningStatusHistory history = recordDTO.getHistories().get(0);
|
|
|
|
|
|
|
|
|
|
|
|
String[] parts = k.split(":");
|
|
|
|
|
|
String deviceId = parts[1];
|
2026-07-14 12:43:23 +08:00
|
|
|
|
NettyDevice slaveDevice = sessionManager.getDevice(deviceId);
|
2026-08-25 12:36:10 +08:00
|
|
|
|
if (slaveDevice != null && slaveDevice.getOnlineStatus() == 1) {
|
2026-07-29 13:08:49 +08:00
|
|
|
|
Long siteId = slaveDevice.getDevice().getSiteId();
|
|
|
|
|
|
Long orgId = slaveDevice.getDevice().getOrgId();
|
|
|
|
|
|
log.debug("compare siteId:{},orgId:{}", siteId, orgId);
|
|
|
|
|
|
SiteMemory siteMemory = GlobalMemory.getSiteMemory(orgId, siteId);
|
|
|
|
|
|
if (siteMemory != null) {
|
|
|
|
|
|
List<AlarmMessage> compared = compareErrorStandard(siteId, orgId, history,
|
|
|
|
|
|
siteMemory.standards.get(ErrorSource.MOWER));
|
|
|
|
|
|
DeviceErrorPushDTO pushDTO = new DeviceErrorPushDTO();
|
|
|
|
|
|
pushDTO.setDeviceId(deviceId);
|
|
|
|
|
|
pushDTO.setTime(System.currentTimeMillis());
|
|
|
|
|
|
pushDTO.setDetails(compared);
|
|
|
|
|
|
pushDTO.setEvent(RespondCode.device_error_push);
|
|
|
|
|
|
pushList.add(pushDTO);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2026-07-09 08:40:32 +08:00
|
|
|
|
// 按实际deviceId分组,推送错误信息
|
|
|
|
|
|
Map<String, List<DeviceErrorPushDTO>> pushMap = pushList.stream()
|
|
|
|
|
|
.collect(java.util.stream.Collectors.groupingBy(DeviceErrorPushDTO::getDeviceId));
|
|
|
|
|
|
pushMap.forEach((deviceId, dtos) -> {
|
|
|
|
|
|
// pushErrorMessage(deviceId, JSON.toJSONString(dtos));
|
|
|
|
|
|
// todo 判断错误级别,是否需要推送邮件 或者钉钉。
|
|
|
|
|
|
// 找到这个设备的场站 添加场站是否开启关闭 钉钉或者邮件推送,推送邮件 添加人员是否订阅邮件,钉钉是加入钉钉群
|
|
|
|
|
|
alertPushService.messagePushHandler(deviceId, dtos);
|
|
|
|
|
|
});
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("执行监测错误线程错误:{}", e.getMessage());
|
|
|
|
|
|
}
|
2026-07-14 12:43:23 +08:00
|
|
|
|
}, 0, 5, TimeUnit.SECONDS);
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void initStandard() throws IOException {
|
2026-07-14 12:43:23 +08:00
|
|
|
|
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()));
|
2026-07-09 08:40:32 +08:00
|
|
|
|
}
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
2026-07-14 12:43:23 +08:00
|
|
|
|
});
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void pushErrorMessage(String deviceId, String dto) {
|
2026-07-09 08:40:32 +08:00
|
|
|
|
// NettyDevice device = sessionManager.getDevice(deviceId);
|
|
|
|
|
|
// if (device != null) {
|
|
|
|
|
|
// ByteBuf buf = Unpooled.buffer();
|
|
|
|
|
|
// CommandUtils.buildCommand(buf, dto, CommandConstant.interaction);
|
|
|
|
|
|
// if (device.getChannel() != null && device.getChannel().isActive()) {
|
|
|
|
|
|
// device.getChannel().writeAndFlush(buf);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
try {
|
2026-09-09 09:01:54 +08:00
|
|
|
|
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
|
|
|
|
|
String.format(MqttTopic.DEVICE_ERROR_PUSH_TOPIC, deviceId), dto);
|
|
|
|
|
|
// GlobalMemory.mqttClientUtil.publish(String.format(MqttTopic.DEVICE_ERROR_PUSH_TOPIC,
|
|
|
|
|
|
// deviceId), dto);
|
2026-07-09 08:40:32 +08:00
|
|
|
|
List<NettyDevice> controlMasters = sessionManager.getAllSlaveControl(deviceId);
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(controlMasters)) {
|
|
|
|
|
|
controlMasters.forEach(x -> {
|
|
|
|
|
|
websocketMesDispather.dispather(x.getConnectorId(), dto);
|
|
|
|
|
|
log.info("推送错误信息 device:{},content:{}", deviceId, dto);
|
|
|
|
|
|
});
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
2026-08-19 16:57:55 +08:00
|
|
|
|
} catch (Exception e) {
|
2026-07-09 08:40:32 +08:00
|
|
|
|
log.error("推送错误信息失败 device:{}error:{}", deviceId, e.getMessage());
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-14 12:43:23 +08:00
|
|
|
|
public List<AlarmMessage> compareErrorStandard(Long siteId, Long orgId, DeviceRunningStatusHistory history,
|
2026-09-09 09:01:54 +08:00
|
|
|
|
List<ErrorIdentificationStandard> standards) {
|
2026-07-09 08:40:32 +08:00
|
|
|
|
if (history == null || CollectionUtils.isEmpty(standards))
|
|
|
|
|
|
return null;
|
|
|
|
|
|
List<AlarmMessage> list = new ArrayList<>();
|
2026-04-17 10:42:16 +08:00
|
|
|
|
standards.forEach(standard -> {
|
|
|
|
|
|
String fieldName = standard.getField();
|
|
|
|
|
|
String compareValues = standard.getCompareValues();
|
|
|
|
|
|
CompareEnum compareType = standard.getCompareType();
|
|
|
|
|
|
String targetValue = knownClassFieldFinding(fieldName, history);
|
2026-09-09 09:01:54 +08:00
|
|
|
|
log.debug("compare2 compareType:{} compareValues:{},targetValue:{}", compareType, compareValues,
|
|
|
|
|
|
targetValue);
|
2026-04-17 10:42:16 +08:00
|
|
|
|
if (!StringUtils.isEmpty(compareValues) && !StringUtils.isEmpty(targetValue)) {
|
2026-07-29 13:08:49 +08:00
|
|
|
|
boolean result = CompareUtils.compare(compareType, targetValue, compareValues);
|
|
|
|
|
|
log.debug("compare3 result:{}", result);
|
|
|
|
|
|
if (result) {
|
2026-07-09 08:40:32 +08:00
|
|
|
|
AlarmMessage alarm = new AlarmMessage();
|
|
|
|
|
|
alarm.setContent(standard.getErrorDescription());
|
|
|
|
|
|
alarm.setDeviceSn(history.getDeviceId());
|
|
|
|
|
|
alarm.setDeviceName(history.getDeviceId());
|
|
|
|
|
|
alarm.setLevel(standard.getErrorLevel());
|
|
|
|
|
|
alarm.setLocation(history.getLatitude() + "," + history.getLongitude());
|
|
|
|
|
|
alarm.setName(standard.getErrorName());
|
|
|
|
|
|
alarm.setNo(standard.getErrorCode());
|
|
|
|
|
|
alarm.setSuggestion(standard.getSuggestion());
|
|
|
|
|
|
alarm.setStatus("未处理");
|
2026-07-29 13:08:49 +08:00
|
|
|
|
alarm.setTimeValues(targetValue);
|
2026-07-09 08:40:32 +08:00
|
|
|
|
alarm.setTime(LocalDateTime.now());
|
2026-07-14 12:43:23 +08:00
|
|
|
|
alarm.setOrgId(orgId);
|
|
|
|
|
|
alarm.setSiteId(siteId);
|
2026-07-09 08:40:32 +08:00
|
|
|
|
list.add(alarm);
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static String knownClassFieldFinding(String fieldName, DeviceRunningStatusHistory history) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 1. 获取类的Class对象
|
|
|
|
|
|
Class<?> historyClass = DeviceRunningStatusHistory.class;
|
|
|
|
|
|
Field field = historyClass.getDeclaredField(fieldName);
|
|
|
|
|
|
field.setAccessible(true);
|
|
|
|
|
|
Object value = field.get(history);
|
|
|
|
|
|
return (String) value;
|
|
|
|
|
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
|
|
|
|
System.out.println("获取字段失败: " + e.getMessage());
|
|
|
|
|
|
log.error("获取属性值失败:{}", e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-19 11:02:52 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 监控心跳
|
|
|
|
|
|
*/
|
|
|
|
|
|
public void heartBeatMonitor() {
|
|
|
|
|
|
executor.scheduleWithFixedDelay(() -> {
|
|
|
|
|
|
try {
|
|
|
|
|
|
Long nowTime = System.currentTimeMillis();
|
|
|
|
|
|
List<HeartBeatDTO> heartBeatDTOS = GlobalMemory.customMqttDeviceMonitor.getAllHeartBeat();
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(heartBeatDTOS)) {
|
|
|
|
|
|
heartBeatDTOS.forEach(x -> {
|
2026-08-19 16:57:55 +08:00
|
|
|
|
String deviceId = x.getSn();
|
2026-08-19 11:02:52 +08:00
|
|
|
|
Long lastActiveTime = x.getSysTimestamp();
|
2026-08-19 16:57:55 +08:00
|
|
|
|
NettyDevice nettyDevice = sessionManager.getDevice(x.getSn());
|
2026-08-19 11:02:52 +08:00
|
|
|
|
if (nowTime - lastActiveTime >= Constant.hostOfflineInterval) {
|
2026-09-09 09:01:54 +08:00
|
|
|
|
// 超时了判断离线
|
2026-08-19 16:57:55 +08:00
|
|
|
|
if (nettyDevice != null) {
|
2026-09-09 09:01:54 +08:00
|
|
|
|
nettyDevice.status(DeviceStatus.offline.getType());
|
|
|
|
|
|
// todo 推送设备离线
|
|
|
|
|
|
String key = NettyCacheKey.latestPositonKey + deviceId;
|
|
|
|
|
|
// 保存一下最新一次的数据到 数据库
|
|
|
|
|
|
LocationMessage locationMessage = redisCache.getCacheObject(key);
|
|
|
|
|
|
if (locationMessage != null) {
|
|
|
|
|
|
LambdaQueryWrapper<LocationMessage> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
|
queryWrapper.eq(LocationMessage::getDeviceId, deviceId);
|
|
|
|
|
|
LocationMessage existing = hostLocationMapper.selectOne(queryWrapper);
|
|
|
|
|
|
if (existing != null) {
|
|
|
|
|
|
locationMessage.setId(existing.getId());
|
|
|
|
|
|
}
|
|
|
|
|
|
hostLocationMapper.saveOrUpdate(locationMessage);
|
|
|
|
|
|
}
|
2026-08-19 11:02:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2026-08-19 16:57:55 +08:00
|
|
|
|
if (nettyDevice == null) {
|
|
|
|
|
|
sessionManager.registerSlaveDevice(deviceId, ConnectorStatus.ACTIVE, null);
|
|
|
|
|
|
Device device = deviceService.selectDeviceBySerialNumber(deviceId);
|
|
|
|
|
|
if (device == null) {
|
|
|
|
|
|
device = new Device();
|
|
|
|
|
|
device.setStatus(3);
|
|
|
|
|
|
device.setOnlineStatus(DeviceStatus.online.getType());
|
|
|
|
|
|
device.setSerialNumber(deviceId);
|
|
|
|
|
|
device.setDeviceName(deviceId);
|
|
|
|
|
|
device.setProductId(-1L);
|
|
|
|
|
|
device.setTenantId(-1L);
|
|
|
|
|
|
device.setFirmwareVersion(BigDecimal.valueOf(1.0));
|
|
|
|
|
|
device.setProductName("割草机产品MC700");
|
|
|
|
|
|
device.setCreateTime(LocalDateTime.now());
|
|
|
|
|
|
device.setUpdateTime(LocalDateTime.now());
|
2026-09-09 09:01:54 +08:00
|
|
|
|
device.setHasHost(true);
|
2026-08-19 16:57:55 +08:00
|
|
|
|
deviceService.insertDeviceBySelf(device);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
device.setStatus(3);
|
|
|
|
|
|
device.setOnlineStatus(DeviceStatus.online.getType());
|
|
|
|
|
|
device.setUpdateTime(LocalDateTime.now());
|
2026-09-09 09:01:54 +08:00
|
|
|
|
if (!device.isHasHost()) {
|
|
|
|
|
|
device.setHasHost(true);
|
|
|
|
|
|
}
|
2026-08-19 16:57:55 +08:00
|
|
|
|
deviceService.updateDeviceBySelf(device);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 推送json 找到设备绑定的主机进行推送
|
2026-09-09 09:01:54 +08:00
|
|
|
|
// List<NettyDevice> controlMasters =
|
|
|
|
|
|
// sessionManager.getAllSlaveControl(device.getSerialNumber());
|
|
|
|
|
|
// if (!CollectionUtils.isEmpty(controlMasters)) {
|
|
|
|
|
|
// controlMasters.forEach(x -> {
|
|
|
|
|
|
// DeviceStatusChangeDTO changeDTO = new DeviceStatusChangeDTO();
|
|
|
|
|
|
// changeDTO.setDeviceId(data);
|
|
|
|
|
|
// changeDTO.setStatus(DeviceStatus.online.getCode());
|
|
|
|
|
|
// changeDTO.setEvent(RespondCode.device_status_changed);
|
|
|
|
|
|
// ByteBuf buf = ctx.alloc().buffer();
|
|
|
|
|
|
// CommandUtils.buildCommand(buf, changeDTO, CommandConstant.interaction);
|
|
|
|
|
|
// String content = buf.toString(CharsetUtil.UTF_8);
|
|
|
|
|
|
// logger.info("推送下位机登录状态消息:{}", content);
|
|
|
|
|
|
// if (x.getChannel() != null && x.getChannel().isActive()) {
|
|
|
|
|
|
// x.getChannel().writeAndFlush(buf);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// });
|
2026-08-19 16:57:55 +08:00
|
|
|
|
} else {
|
2026-09-09 09:01:54 +08:00
|
|
|
|
// todo 推送设备上线
|
2026-08-19 16:57:55 +08:00
|
|
|
|
nettyDevice.status(1);
|
|
|
|
|
|
}
|
2026-08-19 11:02:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("执行监测心跳线程错误:{}", e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 0, 500, TimeUnit.MILLISECONDS);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-17 10:42:16 +08:00
|
|
|
|
}
|