#优化路径规划下发 任务状态接收相关
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package com.maibu.core.business.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.enums.MesType;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WebRouteStatusMessageDTO {
|
||||
private List<LatAndLngEntity> data;
|
||||
private String deviceId;
|
||||
private Long taskId;
|
||||
private MesType type;
|
||||
}
|
||||
@@ -14,5 +14,6 @@ public enum MesType {
|
||||
remoteControl,
|
||||
detectionReport, // 障碍物消息
|
||||
switchPermission, // 切换控制申请
|
||||
switchResult;// 切换结果
|
||||
switchResult,// 切换结果
|
||||
route_post;// 路径规划 点位推送
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.maibu.memory;
|
||||
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.maibu.core.business.device.Connector;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
@@ -30,7 +29,7 @@ public class DeviceSessionManager {
|
||||
// 设备ID -> 设备对象(业务实体)
|
||||
private final ConcurrentHashMap<String, NettyDevice> deviceMap = new ConcurrentHashMap<>();
|
||||
|
||||
//当前设备的控制权在哪 登录的账号 deviceId(下位机) -> token key 唯一保证一个deviceId 只有一个控制权
|
||||
// 当前设备的控制权在哪 登录的账号 deviceId(下位机) -> token key 唯一保证一个deviceId 只有一个控制权
|
||||
private final ConcurrentHashMap<String, String> controllerMap = new ConcurrentHashMap<>();
|
||||
|
||||
// 设备ID -> Channel(通信通道)
|
||||
@@ -39,7 +38,6 @@ public class DeviceSessionManager {
|
||||
// Channel -> 设备ID(反查)
|
||||
private final ConcurrentHashMap<Channel, String> channelToDeviceIdMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public void clearChannelToDeviceIdMap(String deviceId) {
|
||||
if (StringUtils.isEmpty(deviceId) || CollectionUtils.isEmpty(channelToDeviceIdMap)) {
|
||||
return;
|
||||
@@ -67,7 +65,6 @@ public class DeviceSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册设备连接(设备上线)
|
||||
*
|
||||
@@ -75,7 +72,8 @@ public class DeviceSessionManager {
|
||||
* @param channel 通信通道
|
||||
* @param deviceType 设备类型(MASTER/SLAVE)
|
||||
*/
|
||||
public void registerDevice(String deviceId, Channel channel, ConnectorType deviceType, ConnectorStatus status, String slaveId) {
|
||||
public void registerDevice(String deviceId, Channel channel, ConnectorType deviceType, ConnectorStatus status,
|
||||
String slaveId) {
|
||||
NettyDevice nettyDevice = deviceMap.computeIfAbsent(deviceId, id -> new NettyDevice(id, deviceType));
|
||||
nettyDevice.setChannel(channel);
|
||||
nettyDevice.setConnectorStatus(status); // 默认上线即ACTIVE
|
||||
@@ -109,7 +107,8 @@ public class DeviceSessionManager {
|
||||
*/
|
||||
public void bindConnector(String masterId, String slaveId) {
|
||||
NettyDevice master = deviceMap.get(masterId);
|
||||
if (master == null) return;
|
||||
if (master == null)
|
||||
return;
|
||||
NettyDevice slave = deviceMap.computeIfAbsent(slaveId, id -> new NettyDevice(id, ConnectorType.SLAVE));
|
||||
master.addConnectedDevice(slave);
|
||||
System.out.println("Bind connectors for master " + masterId + " and slave " + slaveId);
|
||||
@@ -147,7 +146,6 @@ public class DeviceSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean unLock(String token) {
|
||||
if (!StringUtils.isEmpty(token)) {
|
||||
Iterator<String> iterator = controllerMap.keySet().iterator();
|
||||
@@ -179,7 +177,6 @@ public class DeviceSessionManager {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 模糊匹配
|
||||
public List<NettyDevice> getDevicesLike(String query) {
|
||||
return deviceMap.values().stream()
|
||||
@@ -187,7 +184,6 @@ public class DeviceSessionManager {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public List<NettyDevice> getSlaveControl(String slaveId) {
|
||||
// 获取所有连接的主机 且是active状态的
|
||||
return deviceMap.values().stream()
|
||||
@@ -196,7 +192,6 @@ public class DeviceSessionManager {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public List<NettyDevice> getAllSlaveControl(String slaveId) {
|
||||
// 获取所有连接的主机 不区分状态
|
||||
return deviceMap.values().stream()
|
||||
@@ -212,7 +207,6 @@ public class DeviceSessionManager {
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/// 模糊匹配
|
||||
public NettyDevice getUserControl(String userName) {
|
||||
return deviceMap.values().stream()
|
||||
@@ -221,7 +215,6 @@ public class DeviceSessionManager {
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据设备ID获取Channel
|
||||
*/
|
||||
@@ -236,7 +229,6 @@ public class DeviceSessionManager {
|
||||
return channelToDeviceIdMap.get(channel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据从机查控制的主机
|
||||
*/
|
||||
@@ -249,7 +241,8 @@ public class DeviceSessionManager {
|
||||
* 根据从机查所有主机
|
||||
*/
|
||||
public List<NettyDevice> getMastersBySlaveId(String slaveId) {
|
||||
return deviceMap.values().stream().filter(x -> Objects.equals(x.getCurrentSlaveId(), slaveId)).collect(Collectors.toList());
|
||||
return deviceMap.values().stream().filter(x -> Objects.equals(x.getCurrentSlaveId(), slaveId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,12 +250,12 @@ public class DeviceSessionManager {
|
||||
*/
|
||||
public void removeDevice(String deviceId) {
|
||||
NettyDevice nettyDevice = deviceMap.remove(deviceId);
|
||||
// Channel channel = channelMap.remove(deviceId);
|
||||
// Channel channel = channelMap.remove(deviceId);
|
||||
clearChannelToDeviceIdMap(deviceId);
|
||||
// if (channel != null) {
|
||||
// channelToDeviceIdMap.remove(channel);
|
||||
// channel.close();
|
||||
// }
|
||||
// if (channel != null) {
|
||||
// channelToDeviceIdMap.remove(channel);
|
||||
// channel.close();
|
||||
// }
|
||||
if (nettyDevice != null) {
|
||||
// 仅当设备是上位机时,才解绑绑定关系
|
||||
if (nettyDevice.getDeviceType() == ConnectorType.MASTER) {
|
||||
@@ -281,7 +274,6 @@ public class DeviceSessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断设备是否在线
|
||||
*/
|
||||
@@ -306,5 +298,20 @@ public class DeviceSessionManager {
|
||||
return nettyDevice != null && nettyDevice.canReceive();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端当前 控制的设备
|
||||
*/
|
||||
public String getDeviceByTaskId(Long taskId) {
|
||||
if (taskId == null) {
|
||||
return null;
|
||||
}
|
||||
for (String key : deviceMap.keySet()) {
|
||||
NettyDevice nettyDevice = deviceMap.get(key);
|
||||
if (nettyDevice != null && Objects.equals(nettyDevice.getCurrentTaskId(), taskId)) {
|
||||
return nettyDevice.getConnectorId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ public class GlobalMemory {
|
||||
MqttTopic.MOWER_HEARTBEAT,//心跳
|
||||
MqttTopic.MOWER_WILDCARD_LOCATION,//位置 经纬度
|
||||
MqttTopic.MOWER_WILDCARD_TASK_ROUTE, //路径回复
|
||||
MqttTopic.MOWER_WILDCARD_TASK_STATUS,//任务状态
|
||||
MqttTopic.MOWER_WILDCARD_ERROR,//错误
|
||||
MqttTopic.MOWER_WILDCARD_REALTIME, //状态消息
|
||||
MqttTopic.MOWER_WILDCARD_TASK_TARGET_REPLY //路径规划下发回复
|
||||
|
||||
@@ -74,21 +74,17 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
case "realtime_post":
|
||||
handleRealtimePost(deviceId, topic, payload);
|
||||
break;
|
||||
case "status_post":
|
||||
handleStatusPost(deviceId, topic, payload);
|
||||
break;
|
||||
case "heartbeat_post":
|
||||
handleHeartbeatPost(deviceId, topic, payload);
|
||||
break;
|
||||
case "error_post":
|
||||
handleErrorPost(deviceId, topic, payload);
|
||||
break;
|
||||
case "route_post":
|
||||
case "point_post":
|
||||
handleTaskPost(deviceId, topic, payload, action);
|
||||
break;
|
||||
// case "route_post":
|
||||
// case "point_post":
|
||||
// handleTaskPost(deviceId, topic, payload, action);
|
||||
// break;
|
||||
case "task_status_post":
|
||||
case "task_finish_post":
|
||||
handleTaskPost(deviceId, topic, payload, action);
|
||||
break;
|
||||
case "config_reply":
|
||||
@@ -357,13 +353,11 @@ public class HostMessageHandler implements CustomMqttMessageHandler {
|
||||
|
||||
if (remaining.equals("property/location/post")) return "location_post";
|
||||
if (remaining.equals("property/realtime/post")) return "realtime_post";
|
||||
if (remaining.equals("event/status/post")) return "status_post";
|
||||
if (remaining.equals("event/heartbeat/post")) return "heartbeat_post";
|
||||
if (remaining.equals("event/error/post")) return "error_post";
|
||||
if (remaining.equals("task/route/post")) return "route_post";
|
||||
if (remaining.equals("task/point/post")) return "point_post";
|
||||
// if (remaining.equals("task/route/post")) return "route_post";
|
||||
// if (remaining.equals("task/point/post")) return "point_post";
|
||||
if (remaining.equals("task/status/post")) return "task_status_post";
|
||||
if (remaining.equals("task/finish/post")) return "task_finish_post";
|
||||
if (remaining.equals("action/config/reply")) return "config_reply";
|
||||
if (remaining.equals("action/control/reply")) return "control_reply";
|
||||
if (remaining.equals("task/target/reply")) return "route_reply";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.maibu.mqtt;
|
||||
|
||||
|
||||
public class MqttTopic {
|
||||
|
||||
/** @deprecated 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
@@ -13,6 +12,7 @@ public class MqttTopic {
|
||||
public static final String DEVICE_TASK_ARRIVE_TOPIC = "task/%s/arrive";
|
||||
/** @deprecated 通用设备主题,建议使用 MOWER_* 系列主题 */
|
||||
public static final String DEVICE_ERROR_PUSH_TOPIC = "device/%s/error";
|
||||
public static final String DEVICE_ROUTE_PUSH_TOPIC = "device/%s/route/post";
|
||||
|
||||
/** 产品标识:割草机 */
|
||||
public static final String MOWER_PRODUCT = "mower";
|
||||
@@ -47,8 +47,9 @@ public class MqttTopic {
|
||||
|
||||
// ==================== 任务管理 ====================
|
||||
/** 路径规划下发(平台->设备),对应 TCP 0x01 path */
|
||||
// public static final String MOWER_TASK_ROUTE_SET = "mower/%s/task/route/set";
|
||||
// public static final String MOWER_TASK_ROUTE_POST = "mower/%s/task/route/post";
|
||||
// public static final String MOWER_TASK_ROUTE_SET = "mower/%s/task/route/set";
|
||||
// public static final String MOWER_TASK_ROUTE_POST =
|
||||
// "mower/%s/task/route/post";
|
||||
|
||||
public static final String MOWER_TASK_ROUTE_SET = "mower/%s/task/target/set";
|
||||
|
||||
@@ -57,28 +58,32 @@ public class MqttTopic {
|
||||
public static final String MOWER_TASK_POINT_POST = "mower/%s/task/point/post";
|
||||
/** 任务状态变更上报:执行中/暂停/完成等(设备->平台) */
|
||||
public static final String MOWER_TASK_STATUS_POST = "mower/%s/task/status/post";
|
||||
/** 任务完成上报(设备->平台) */
|
||||
public static final String MOWER_TASK_FINISH_POST = "mower/%s/task/finish/post";
|
||||
|
||||
// ==================== 错误告警 ====================
|
||||
/** 设备错误告警上报:电机故障/传感器异常等(设备->平台) */
|
||||
public static final String MOWER_ERROR_POST = "mower/%s/event/error/post";
|
||||
|
||||
// ==================== OTA 固件升级 ====================
|
||||
// /** 下发 OTA 升级指令(平台->设备) */
|
||||
// public static final String MOWER_OTA_UPGRADE_SET = "mower/%s/ota/upgrade/set";
|
||||
// /** OTA 升级进度上报(设备->平台) */
|
||||
// public static final String MOWER_OTA_PROGRESS_POST = "mower/%s/ota/progress/post";
|
||||
// /** OTA 升级结果上报(设备->平台) */
|
||||
// public static final String MOWER_OTA_RESULT_POST = "mower/%s/ota/result/post";
|
||||
// /** 下发 OTA 升级指令(平台->设备) */
|
||||
// public static final String MOWER_OTA_UPGRADE_SET =
|
||||
// "mower/%s/ota/upgrade/set";
|
||||
// /** OTA 升级进度上报(设备->平台) */
|
||||
// public static final String MOWER_OTA_PROGRESS_POST =
|
||||
// "mower/%s/ota/progress/post";
|
||||
// /** OTA 升级结果上报(设备->平台) */
|
||||
// public static final String MOWER_OTA_RESULT_POST =
|
||||
// "mower/%s/ota/result/post";
|
||||
|
||||
// ==================== 设备信息 ====================
|
||||
// /** 查询设备信息(平台->设备) */
|
||||
// public static final String MOWER_INFO_DEVICE_GET = "mower/%s/info/device/get";
|
||||
// /** 设备信息响应(设备->平台) */
|
||||
// public static final String MOWER_INFO_DEVICE_REPLY = "mower/%s/info/device/reply";
|
||||
// /** 查询设备信息(平台->设备) */
|
||||
// public static final String MOWER_INFO_DEVICE_GET =
|
||||
// "mower/%s/info/device/get";
|
||||
// /** 设备信息响应(设备->平台) */
|
||||
// public static final String MOWER_INFO_DEVICE_REPLY =
|
||||
// "mower/%s/info/device/reply";
|
||||
/** 设备版本信息上报(设备->平台) */
|
||||
// public static final String MOWER_INFO_VERSION_POST = "mower/%s/info/version/post";
|
||||
// public static final String MOWER_INFO_VERSION_POST =
|
||||
// "mower/%s/info/version/post";
|
||||
|
||||
// ==================== 通配符订阅 ====================
|
||||
/** 订阅所有设备的状态变更事件 */
|
||||
@@ -98,9 +103,6 @@ public class MqttTopic {
|
||||
|
||||
public static final String MOWER_HEARTBEAT = "mower/+/event/heartbeat/post";
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 格式化 Topic 模板,将 %s 替换为设备ID
|
||||
*
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.maibu.netty.handler;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
@@ -8,7 +7,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.maibu.memory.DeviceSessionManager;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
@@ -24,8 +22,6 @@ import com.maibu.constant.Constant;
|
||||
import com.maibu.core.business.Device;
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.business.inter.WebsocketMesDispather;
|
||||
import com.maibu.core.domain.entity.SysUser;
|
||||
import com.maibu.core.domain.entity.UserClient;
|
||||
import com.maibu.core.enums.CommandRequestType;
|
||||
import com.maibu.core.enums.ConnectionCloseReason;
|
||||
import com.maibu.core.enums.ConnectorStatus;
|
||||
@@ -34,12 +30,12 @@ import com.maibu.core.enums.DeviceStatus;
|
||||
import com.maibu.core.enums.DeviceTaskStaus;
|
||||
import com.maibu.core.enums.MesType;
|
||||
import com.maibu.core.enums.RespondCode;
|
||||
import com.maibu.dto.DeviceLoginResponseDTO;
|
||||
import com.maibu.dto.DeviceRequestDTO;
|
||||
import com.maibu.dto.DeviceRespondDTO;
|
||||
import com.maibu.dto.DeviceStatusChangeDTO;
|
||||
import com.maibu.dto.DeviceTaskStatusMessageDTO;
|
||||
import com.maibu.mapper.DeviceRunStatisticsMapper;
|
||||
import com.maibu.memory.DeviceSessionManager;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.mqtt.MqttTopic;
|
||||
import com.maibu.service.IDeviceService;
|
||||
@@ -74,9 +70,6 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private DeviceRunStatisticsMapper deviceRunStatisticsMapper;
|
||||
|
||||
@@ -190,7 +183,7 @@ public class DeviceConnectHandler extends SimpleChannelInboundHandler<String> {
|
||||
|
||||
NettyDevice masterDevice = sessionManager.getDevice(sessionId);
|
||||
if (masterDevice == null) {
|
||||
// sessionManager.getControl(sessionId);
|
||||
// sessionManager.getControl(sessionId);
|
||||
handleMasterConnect(ctx, sessionId, null, ConnectorStatus.ACTIVE);
|
||||
} else {
|
||||
ctx.channel().attr(Constant.ATT_DEVICE_ID).set(sessionId);
|
||||
|
||||
@@ -333,7 +333,7 @@ public class TransferDeviceService {
|
||||
}
|
||||
masterDevice.setCurrentSlaveId(slaveId);
|
||||
masterDevice.setConnectorStatus(ConnectorStatus.ACTIVE);
|
||||
sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
|
||||
// sysUserClientService.updateAliveStatus(masterDevice.getConnectorId(), slaveId, 1);
|
||||
|
||||
dto.setSwitchControl(true);
|
||||
dto.setHolder(platform);
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
package com.maibu.controller;
|
||||
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.R;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.service.impl.HostComputerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
@@ -18,6 +7,32 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.maibu.core.business.device.NettyDevice;
|
||||
import com.maibu.core.business.dto.WebRouteStatusMessageDTO;
|
||||
import com.maibu.core.business.inter.WebsocketMesDispather;
|
||||
import com.maibu.core.business.path.LatAndLngEntity;
|
||||
import com.maibu.core.controller.BaseController;
|
||||
import com.maibu.core.domain.R;
|
||||
import com.maibu.core.enums.MesType;
|
||||
import com.maibu.memory.DeviceSessionManager;
|
||||
import com.maibu.memory.GlobalMemory;
|
||||
import com.maibu.mqtt.MqttTopic;
|
||||
import com.maibu.service.impl.HostComputerService;
|
||||
import com.maibu.utils.json.JsonUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/iot/host")
|
||||
@@ -28,10 +43,21 @@ public class HostComputerController extends BaseController {
|
||||
@Autowired
|
||||
private HostComputerService hostComputerService;
|
||||
|
||||
@Autowired
|
||||
private WebsocketMesDispather websocketMesDispather;
|
||||
|
||||
@Autowired
|
||||
private DeviceSessionManager deviceSessionManager;
|
||||
|
||||
@Value("${mqtt.client-id}")
|
||||
private String mqttClientId;
|
||||
|
||||
/**
|
||||
* 上传 csv.gz 轨迹文件并解析为 LatAndLngEntity 列表(分批处理,每批 BATCH_SIZE 条)
|
||||
*
|
||||
* <p>CSV 格式:第 1 列=cell_index,第 2 列=x(lat),第 3 列=y(lng)</p>
|
||||
* <p>
|
||||
* CSV 格式:第 1 列=cell_index,第 2 列=x(lat),第 3 列=y(lng)
|
||||
* </p>
|
||||
*
|
||||
* @param file csv.gz 压缩文件
|
||||
* @param taskId 任务ID
|
||||
@@ -40,8 +66,7 @@ public class HostComputerController extends BaseController {
|
||||
@PostMapping(value = "/upload-path-csv", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R uploadCsv(
|
||||
@RequestPart("file") MultipartFile file,
|
||||
@RequestParam("taskId") Long taskId
|
||||
) {
|
||||
@RequestParam("taskId") Long taskId) {
|
||||
if (file == null || file.isEmpty()) {
|
||||
return R.fail("文件不能为空");
|
||||
}
|
||||
@@ -61,7 +86,7 @@ public class HostComputerController extends BaseController {
|
||||
int batchIndex = 0;
|
||||
|
||||
try (GZIPInputStream gzipInputStream = new GZIPInputStream(file.getInputStream());
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream))) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream))) {
|
||||
|
||||
String line;
|
||||
int lineNum = 0;
|
||||
@@ -74,7 +99,7 @@ public class HostComputerController extends BaseController {
|
||||
|
||||
String[] values = line.split(",");
|
||||
|
||||
if (lineNum == 1) {
|
||||
if (lineNum < 4) {
|
||||
log.info("CSV 表头: {}", Arrays.toString(values));
|
||||
continue;
|
||||
}
|
||||
@@ -109,7 +134,8 @@ public class HostComputerController extends BaseController {
|
||||
log.info("csv 解析完成: taskId={}, 共 {} 个轨迹点, 分 {} 批处理", taskId, allPath.size(), batchIndex);
|
||||
|
||||
GlobalMemory.taskPathMap.put(taskId, allPath);
|
||||
|
||||
sendMessage(taskId, allPath);
|
||||
// TODO 推送数据到前端
|
||||
|
||||
return R.ok();
|
||||
|
||||
@@ -119,14 +145,46 @@ public class HostComputerController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位信息 经纬度
|
||||
*/
|
||||
private void sendMessage(Long taskId, List<LatAndLngEntity> data) {
|
||||
try {
|
||||
WebRouteStatusMessageDTO dto = new WebRouteStatusMessageDTO();
|
||||
String deviceId = deviceSessionManager.getDeviceByTaskId(taskId);
|
||||
List<NettyDevice> controlMasters = deviceSessionManager
|
||||
.getAllSlaveControl(deviceId);
|
||||
dto.setData(data);
|
||||
dto.setDeviceId(deviceId);
|
||||
dto.setTaskId(taskId);
|
||||
dto.setType(MesType.route_post);
|
||||
if (!CollectionUtils.isEmpty(controlMasters)) {
|
||||
for (NettyDevice x : controlMasters) {
|
||||
try {
|
||||
websocketMesDispather.dispather(x.getConnectorId(), JsonUtils.toJsonString(dto));
|
||||
} catch (Exception e) {
|
||||
log.error("位置数据websocket推送失败: connectorId={}, error={}", x.getConnectorId(),
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
GlobalMemory.customMqttDeviceMonitor.publish(mqttClientId,
|
||||
String.format(MqttTopic.DEVICE_ROUTE_PUSH_TOPIC, deviceId),
|
||||
JsonUtils.toJsonString(dto));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("sendMessage失败: taskId={}", taskId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 CSV 行解析 LatAndLngEntity
|
||||
* 第 2 列(x) → lat,第 3 列(y) → lng
|
||||
* 第 3 列(x) → lat,第 4 列(y) → lng
|
||||
*/
|
||||
private LatAndLngEntity parseLatLng(String[] values) {
|
||||
try {
|
||||
String xStr = values[1].trim();
|
||||
String yStr = values[2].trim();
|
||||
String xStr = values[2].trim();
|
||||
String yStr = values[3].trim();
|
||||
|
||||
if (xStr.isEmpty() || yStr.isEmpty()) {
|
||||
return null;
|
||||
@@ -145,11 +203,13 @@ public class HostComputerController extends BaseController {
|
||||
/**
|
||||
* 分批处理轨迹数据
|
||||
*
|
||||
* <p>每批 BATCH_SIZE 条数据触发一次,可用于:</p>
|
||||
* <p>
|
||||
* 每批 BATCH_SIZE 条数据触发一次,可用于:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>批量入库(insertBatch)</li>
|
||||
* <li>发布 MQTT 消息到上位机</li>
|
||||
* <li>数据校验/统计</li>
|
||||
* <li>批量入库(insertBatch)</li>
|
||||
* <li>发布 MQTT 消息到上位机</li>
|
||||
* <li>数据校验/统计</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param taskId 任务ID
|
||||
@@ -166,10 +226,14 @@ public class HostComputerController extends BaseController {
|
||||
double minLng = Double.MAX_VALUE, maxLng = -Double.MAX_VALUE;
|
||||
|
||||
for (LatAndLngEntity p : path) {
|
||||
if (p.getLat() < minLat) minLat = p.getLat();
|
||||
if (p.getLat() > maxLat) maxLat = p.getLat();
|
||||
if (p.getLng() < minLng) minLng = p.getLng();
|
||||
if (p.getLng() > maxLng) maxLng = p.getLng();
|
||||
if (p.getLat() < minLat)
|
||||
minLat = p.getLat();
|
||||
if (p.getLat() > maxLat)
|
||||
maxLat = p.getLat();
|
||||
if (p.getLng() < minLng)
|
||||
minLng = p.getLng();
|
||||
if (p.getLng() > maxLng)
|
||||
maxLng = p.getLng();
|
||||
}
|
||||
|
||||
log.info("【第 {} 批处理】taskId={}, 本批 {} 条, lat范围=[{}, {}], lng范围=[{}, {}]",
|
||||
|
||||
@@ -67,6 +67,7 @@ public class WebMiddlewareController extends BaseController {
|
||||
});
|
||||
res.put("nettyClientMap", nettyClients);
|
||||
res.put("controllerMap", deviceSessionManager.getControllerMap());
|
||||
res.put("taskPathMap", GlobalMemory.taskPathMap);
|
||||
res.put("siteMemory", GlobalMemory.getAllSiteMemory());
|
||||
return AjaxResult.success(res);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user