From b821735241678a21ddc033aba04ebaf7ce65a3d2 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Thu, 31 Oct 2024 09:49:33 +0800
Subject: [PATCH] 优化结构
---
ard-work/src/main/java/com/ard/tianyu/netty/handler/ClientHandler.java | 2
ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java | 259 +++++++++++--------------------
ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java | 81 ++++++---
ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolEncoder.java | 9
ard-work/src/main/java/com/ard/tianyu/service/ITyService.java | 4
ard-work/src/main/java/com/ard/tianyu/netty/command/notice/UavReadyReplyCmd.java | 3
ard-work/src/main/java/com/ard/tianyu/controller/UavBaseController.java | 1
ard-common/src/main/java/com/ard/common/utils/ByteUtils.java | 71 ++++++++
8 files changed, 225 insertions(+), 205 deletions(-)
diff --git a/ard-common/src/main/java/com/ard/common/utils/ByteUtils.java b/ard-common/src/main/java/com/ard/common/utils/ByteUtils.java
new file mode 100644
index 0000000..a744ebc
--- /dev/null
+++ b/ard-common/src/main/java/com/ard/common/utils/ByteUtils.java
@@ -0,0 +1,71 @@
+package com.ard.common.utils;
+/**
+ * 字节工具类
+ *
+ * @author ruoyi
+ */
+public class ByteUtils {
+
+ /**
+ * 将字节数组转换为十六进制字符串,每个字节以0x格式显示
+ * @param bytes 字节数组
+ * @return 格式化后的字符串
+ */
+ public static String bytesToHexString(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("0x%02X ", b));
+ }
+ return sb.toString().trim();
+ }
+
+ /**
+ * 将字节数组转换为常规字符串
+ * @param bytes 字节数组
+ * @return 字符串
+ */
+ public static String bytesToString(byte[] bytes) {
+ return new String(bytes);
+ }
+
+ /**
+ * 将单个字节转换为0x十六进制格式字符串
+ * @param b 字节
+ * @return 0x格式的字符串
+ */
+ public static String byteToHex(byte b) {
+ return String.format("0x%02X", b);
+ }
+
+ /**
+ * 将十六进制字符串转换为字节数组
+ * @param hexString 十六进制字符串,支持0x前缀
+ * @return 字节数组
+ */
+ public static byte[] hexStringToBytes(String hexString) {
+ hexString = hexString.replaceAll("0x", "").replaceAll("\\s+", "");
+ int length = hexString.length();
+ byte[] data = new byte[length / 2];
+ for (int i = 0; i < length; i += 2) {
+ data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ + Character.digit(hexString.charAt(i+1), 16));
+ }
+ return data;
+ }
+
+ /**
+ * 将字节数组转换为十六进制字符串,每个字节用空格分隔显示
+ * @param bytes 字节数组
+ * @return 格式化后的十六进制字符串
+ */
+ public static String bytesToHexWithSpaces(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < bytes.length; i++) {
+ sb.append(String.format("%02X", bytes[i]));
+ if (i < bytes.length - 1) {
+ sb.append(" ");
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/controller/UavBaseController.java b/ard-work/src/main/java/com/ard/tianyu/controller/UavBaseController.java
index e7a70bc..9a5f5a1 100644
--- a/ard-work/src/main/java/com/ard/tianyu/controller/UavBaseController.java
+++ b/ard-work/src/main/java/com/ard/tianyu/controller/UavBaseController.java
@@ -14,7 +14,6 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
-
import javax.annotation.Resource;
import java.util.List;
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/notice/UavReadyReplyCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/notice/UavReadyReplyCmd.java
index 6ec47f5..2d9d149 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/command/notice/UavReadyReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/notice/UavReadyReplyCmd.java
@@ -18,7 +18,8 @@
private final double longitude; // 经度
private final double latitude; // 纬度
private final int altitude; // 海拔高度
- public UavReadyReplyCmd(String boxSn,byte batteryPower,double longitude,double latitude,int altitude) {
+
+ public UavReadyReplyCmd(String boxSn, byte batteryPower, double longitude, double latitude, int altitude) {
setDataHeader((short) 0x6A77); // 设置帧头
setCmdCode((byte) 0x3D); // 设置指令编号
setDataLength((short) 39); // 数据长度
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/handler/ClientHandler.java b/ard-work/src/main/java/com/ard/tianyu/netty/handler/ClientHandler.java
index 1bef005..35e8ad7 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/handler/ClientHandler.java
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/handler/ClientHandler.java
@@ -31,7 +31,7 @@
InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
String host = ipSocket.getHostString();
int port = ipSocket.getPort();
- tyService.processMessage(host + ":" + port, command);
+ tyService.processReplyMessage(host + ":" + port, command);
}
@Override
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java b/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
index 27fe205..2b811f9 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
@@ -1,6 +1,7 @@
package com.ard.tianyu.netty.handler;// MessageProtocolDecoder.java
-import com.ard.tianyu.netty.command.*;
+import com.ard.common.utils.ByteUtils;
+import com.ard.tianyu.netty.command.BaseCmd;
import com.ard.tianyu.netty.command.camera.CameraModeReplyCmd;
import com.ard.tianyu.netty.command.camera.CapturePicReplyCmd;
import com.ard.tianyu.netty.command.camera.RecordStartReplyCmd;
@@ -16,11 +17,11 @@
import com.ard.tianyu.netty.command.register.RegisterReplyCmd;
import com.ard.tianyu.netty.command.register.UavInitReplyCmd;
import com.ard.tianyu.netty.protobuf.TelemetryDataPB;
+import com.google.protobuf.InvalidProtocolBufferException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
-
import java.util.List;
@Slf4j
@@ -45,6 +46,7 @@
}
byte cmdCode = in.readByte();
BaseCmd baseCmd = null;
+ byte actionCode;
switch (cmdCode) {
case 0x01:
byte success = in.readByte(); // 读取是否成功
@@ -56,13 +58,10 @@
baseCmd = new HeartbeatReplyCmd(timestamp);
log.debug("心跳回复: 时间戳 {}", timestamp);
break;
- case 0x03:
- case 0x04:
- break;
case 0x0A:
byte status = in.readByte();
baseCmd = new BoxPowerStatusReplyCmd(status);
- log.debug("云盒开机/关机通知回复: 状态 {}", String.format("0x%02X", status & 0xFF));
+ log.debug("云盒开机/关机通知回复: 状态 {}", ByteUtils.byteToHex(status));
break;
case (byte) 0xA8:
byte[] uavStatus = new byte[dataLength - 1];
@@ -72,181 +71,109 @@
log.debug("无人机状态数据: {}", uavState.getBoxSn());
break;
case (byte) 0xA9:
- byte[] uavData = new byte[dataLength - 1];
- in.readBytes(uavData);
- TelemetryDataPB.TelemetryData telemetryData = TelemetryDataPB.TelemetryData.parseFrom(uavData);
+ byte[] telemetryDataBytes = new byte[dataLength - 1];
+ in.readBytes(telemetryDataBytes);
+ TelemetryDataPB.TelemetryData telemetryData = TelemetryDataPB.TelemetryData.parseFrom(telemetryDataBytes);
baseCmd = new UavTelemetryDataCmd(telemetryData);
log.debug("遥测数据: {}", telemetryData.getBoxSn());
break;
case (byte) 0x0C:
int delayTime = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- // String boxSn12 = new String(uavData);
- uavData = new byte[dataLength - 20];
- in.readBytes(uavData);
- TelemetryDataPB.SignalInfo signalInfo = TelemetryDataPB.SignalInfo.parseFrom(uavData);
+ byte[] signalInfoBytes = new byte[15];
+ in.readBytes(signalInfoBytes);
+ signalInfoBytes = new byte[dataLength - 20];
+ in.readBytes(signalInfoBytes);
+ TelemetryDataPB.SignalInfo signalInfo = TelemetryDataPB.SignalInfo.parseFrom(signalInfoBytes);
baseCmd = new SignalInfoCmd(signalInfo);
log.debug("信道质量数据: {}", delayTime);
break;
case (byte) 0xD1:
- byte encryptionFlag = in.readByte();
- byte actionCode = in.readByte();
- switch (actionCode) {
- case 0x11:
- byte result = in.readByte();
- int errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- String boxSn = new String(uavData);
- baseCmd = new TakeOffReplyCmd(boxSn, result, errorCode);
- log.debug("起飞回复: {}", boxSn);
- break;
- case 0x12:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new ReturnHomeReplyCmd(boxSn, result, errorCode);
- log.debug("返航回复: {}", boxSn);
- break;
- case 0x13:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new ReturnHomeCancelReplyCmd(boxSn, result, errorCode);
- log.debug("取消返航回复: {}", boxSn);
- break;
- case 0x14:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new LandReplyCmd(boxSn, result, errorCode);
- log.debug("降落回复: {}", boxSn);
- break;
- case 0x15:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new LandCancelReplyCmd(boxSn, result, errorCode);
- log.debug("取消降落回复: {}", boxSn);
- break;
- case 0x29:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new LandForcedReplyCmd(boxSn, result, errorCode);
- log.debug("强制降落回复: {}", boxSn);
- break;
- case 0x32:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new EmergencyBrakeReplyCmd(boxSn, result, errorCode);
- log.debug("紧急制动回复: {}", boxSn);
- break;
- case 0x39:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new PointControlReachedReplyCmd(boxSn, result, errorCode);
- log.debug("到达指点飞行位置回复: {}", boxSn);
- break;
- case 0x22:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new CameraModeReplyCmd(boxSn, result, errorCode);
- log.debug("设置相机模式回复: {}", boxSn);
- break;
- case 0x23:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new CapturePicReplyCmd(boxSn, result, errorCode);
- log.debug("拍照回复: {}", boxSn);
- break;
- case 0x24:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new RecordStartReplyCmd(boxSn, result, errorCode);
- log.debug("开始录像回复: {}", boxSn);
- break;
- case 0x25:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new RecordStopReplyCmd(boxSn, result, errorCode);
- log.debug("停止录像回复: {}", boxSn);
- break;
- case 0x2E:
- result = in.readByte();
- errorCode = in.readInt();
- uavData = new byte[15];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new FlyWayEndReplyCmd(boxSn, result, errorCode);
- log.debug("航线结束通知回复: {}", boxSn);
- break;
- case 0x3D:
- byte batteryPower = in.readByte();
- double longitude = in.readDouble();
- double latitude = in.readDouble();
- int altitude = in.readInt();
- uavData = new byte[dataLength - 24];
- in.readBytes(uavData);
- boxSn = new String(uavData);
- baseCmd = new UavReadyReplyCmd(boxSn, batteryPower, longitude, latitude, altitude);
- log.debug("无人机准备完成通知回复: 电池电量 {}", String.format("0x%02X", batteryPower & 0xFF));
- break;
- case 0x42:
- byte[] uavData1 = new byte[dataLength - 18];
- in.readBytes(uavData1);
- byte[] uavData2 = new byte[15];
- in.readBytes(uavData2);
- boxSn = new String(uavData2);
- TelemetryDataPB.UavInitInfo uavInitInfo = TelemetryDataPB.UavInitInfo.parseFrom(uavData1);
- baseCmd = new UavInitReplyCmd(boxSn, uavInitInfo);
- log.debug("无人机初始化数据: {}", boxSn);
- break;
- default:
- log.warn("无法识别的命令码动作编号:{}", String.format("0x%02X", actionCode & 0xFF));
- break;
- }
+ in.readByte();//加密标志
+ actionCode = in.readByte();//动作编号
+ baseCmd = processD1ReplyCmd(in, actionCode);
break;
default:
- encryptionFlag = in.readByte();
+ in.readByte();//加密标志
actionCode = in.readByte();
- log.warn("无法识别的命令码: {},加密标志:{},动作编号:{}",
- String.format("0x%02X", cmdCode & 0xFF),
- String.format("0x%02X", encryptionFlag & 0xFF),
- String.format("0x%02X", actionCode & 0xFF));//String.format("0x%02X", cmdCode & 0xFF)
-
+ log.warn("无法识别的命令码: {},动作编号:{}",
+ ByteUtils.byteToHex(cmdCode),
+ ByteUtils.byteToHex(actionCode)
+ );
}
if (baseCmd != null) {
out.add(baseCmd);
}
}
+
+ //处理D1指令回复
+ private BaseCmd processD1ReplyCmd(ByteBuf in, byte actionCode) {
+ byte result = in.readByte();
+ int errorCode = in.readInt();
+ byte[] uavData = new byte[15];
+ in.readBytes(uavData);
+ String boxSn = new String(uavData);
+ switch (actionCode) {
+ case 0x11:
+ return new TakeOffReplyCmd(boxSn, result, errorCode);
+ case 0x12:
+ return new ReturnHomeReplyCmd(boxSn, result, errorCode);
+ case 0x13:
+ return new ReturnHomeCancelReplyCmd(boxSn, result, errorCode);
+ case 0x14:
+ return new LandReplyCmd(boxSn, result, errorCode);
+ case 0x15:
+ return new LandCancelReplyCmd(boxSn, result, errorCode);
+ case 0x29:
+ return new LandForcedReplyCmd(boxSn, result, errorCode);
+ case 0x32:
+ return new EmergencyBrakeReplyCmd(boxSn, result, errorCode);
+ case 0x39:
+ return new PointControlReachedReplyCmd(boxSn, result, errorCode);
+ case 0x22:
+ return new CameraModeReplyCmd(boxSn, result, errorCode);
+ case 0x23:
+ return new CapturePicReplyCmd(boxSn, result, errorCode);
+ case 0x24:
+ return new RecordStartReplyCmd(boxSn, result, errorCode);
+ case 0x25:
+ return new RecordStopReplyCmd(boxSn, result, errorCode);
+ case 0x2E:
+ return new FlyWayEndReplyCmd(boxSn, result, errorCode);
+ // Special cases
+ case 0x3D:
+ case 0x42:
+ return processSpecialD1ReplyCmd(in, actionCode, boxSn);
+ // Add other cases...
+ default:
+ log.warn("无法识别的动作编号:{}", ByteUtils.byteToHex(actionCode));
+ }
+ return null;
+ }
+
+ //处理特殊D1指令回复
+ private BaseCmd processSpecialD1ReplyCmd(ByteBuf in, byte actionCode, String boxSn) {
+ switch (actionCode) {
+ //无人机准备完成通知回复
+ case 0x3D:
+ byte batteryPower = in.readByte();
+ double longitude = in.readDouble();
+ double latitude = in.readDouble();
+ int altitude = in.readInt();
+ return new UavReadyReplyCmd(boxSn, batteryPower, longitude, latitude, altitude);
+ //无人机初始化信息回复
+ case 0x42:
+ byte[] uavData1 = new byte[in.readableBytes() - 15];
+ in.readBytes(uavData1);
+ TelemetryDataPB.UavInitInfo uavInitInfo;
+ try {
+ uavInitInfo = TelemetryDataPB.UavInitInfo.parseFrom(uavData1);
+ } catch (InvalidProtocolBufferException e) {
+ throw new RuntimeException(e);
+ }
+ return new UavInitReplyCmd(boxSn, uavInitInfo);
+ default:
+ return null;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolEncoder.java b/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolEncoder.java
index c4dca37..3ff7b6c 100644
--- a/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolEncoder.java
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolEncoder.java
@@ -1,5 +1,6 @@
package com.ard.tianyu.netty.handler;// MessageProtocolEncoder.java
+import com.ard.common.utils.ByteUtils;
import com.ard.tianyu.netty.command.BaseCmd;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -25,11 +26,7 @@
out.getBytes(out.readerIndex(), encodedBytes); // 读取ByteBuf中的字节到字节数组中
// log.warn("Encoded message bytes: {}", Arrays.toString(encodedBytes));
// 将字节数组转换为十六进制格式
- StringBuilder hexString = new StringBuilder();
- for (byte b : encodedBytes) {
- hexString.append(String.format("%02X ", b)); // 将每个字节转换为两位十六进制并加上空格
- }
-
- log.warn("Encoded message in hex: {}", hexString.toString().trim());
+ String hexString = ByteUtils.bytesToHexWithSpaces(encodedBytes);
+ log.warn("Encoded message in hex: {}", hexString);
}
}
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
index 612fcb2..c4f9e4c 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
+++ b/ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
@@ -193,7 +193,7 @@
SignalInfo getSignalInfo(String boxSn);
/**
- * 解析天宇服务端发来的消息
+ * 处理回复消息
*/
- void processMessage(String key, BaseCmd tyMessage);
+ void processReplyMessage(String key, BaseCmd tyMessage);
}
diff --git a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
index 88d749c..c5cd5b7 100644
--- a/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
@@ -1,5 +1,6 @@
package com.ard.tianyu.service.impl;
+import com.ard.common.utils.ByteUtils;
import com.ard.tianyu.config.TyConfiguration;
import com.ard.tianyu.http.TyClient;
import com.ard.tianyu.model.cache.UavSignalInfoCache;
@@ -47,6 +48,8 @@
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* TyServiceImpl
@@ -63,6 +66,9 @@
@Resource
private TyConfiguration tyConfiguration;
+
+ // 存储每个无人机的最后遥测处理时间
+ private Map<String, Long> lastTelemetryTimes = new ConcurrentHashMap<>();
/**
* 获取天宇token信息
@@ -139,29 +145,12 @@
*/
@Override
public void registerMessage() {
- AccessTokenReceiver tyToken = tyConfiguration.getAccessToken();
- RegisterCmd registerMessage = new RegisterCmd(tyToken.getCompanyId(), tyToken.getAccessToken().getBytes());
- this.sendMessage(tyConfiguration.getIpPort(), registerMessage);
- }
-
- /**
- * 发送消息
- */
- public void sendMessage(String key, BaseCmd msg) {
try {
- ChannelFuture future = TyNettyTcpClient.channels.get(key).getChannelFuture();
- Channel channel = future.channel();
- if (channel.isActive()) {
- InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress();
- String host = ipSocket.getHostString();
- int port = ipSocket.getPort();
- channel.writeAndFlush(msg); // 发送编码后的数据
- log.debug("向天宇服务器【{}:{}】发送数据,命令码:{}", host, port, String.format("0x%02X", msg.getCmdCode() & 0xFF));
- } else {
- log.error("与天宇服务器链接断开,无法发送数据!");
- }
+ AccessTokenReceiver tyToken = tyConfiguration.getAccessToken();
+ RegisterCmd registerMessage = new RegisterCmd(tyToken.getCompanyId(), tyToken.getAccessToken().getBytes());
+ this.sendMessage(tyConfiguration.getIpPort(), registerMessage);
} catch (Exception e) {
- log.error("发送消息异常:{}", e.getMessage());
+ log.error("注册天宇平台失败:{}", e.getMessage());
}
}
@@ -366,7 +355,7 @@
*/
@Override
public void emeragencyBrake(EmeragencyBrakeDTO emeragencyBrakeDTO) {
- EmergencyBrakeCmd emergencyBrakeCmd=new EmergencyBrakeCmd(emeragencyBrakeDTO);
+ EmergencyBrakeCmd emergencyBrakeCmd = new EmergencyBrakeCmd(emeragencyBrakeDTO);
this.sendMessage(tyConfiguration.getIpPort(), emergencyBrakeCmd);
}
@@ -398,7 +387,7 @@
* 处理天宇服务器返回的消息
*/
@Override
- public void processMessage(String key, BaseCmd tyCommand) {
+ public void processReplyMessage(String key, BaseCmd tyCommand) {
byte cmdCode = tyCommand.getCmdCode();
switch (cmdCode) {
case 0x01:
@@ -438,10 +427,25 @@
case (byte) 0xA9:
// 处理无人机遥测消息
UavTelemetryDataCmd uavTelemetryDataCmd = (UavTelemetryDataCmd) tyCommand;
- TelemetryData telemetryData = UavTelemetryDataConverter.convertProtoToEntity(uavTelemetryDataCmd.getTelemetryData());
- UavTelemetryDataCache.putUavTelemetryData(telemetryData);
- logPrint("无人机遥测", telemetryData.getBoxSn());
+ String boxSn = ByteUtils.bytesToString(uavTelemetryDataCmd.getBoxSn()); // 假设有获取无人机ID的方法
+ long currentTime = System.currentTimeMillis();
+
+ // 获取无人机的最后处理时间,如果没有则设置为0
+ long lastTelemetryTime = lastTelemetryTimes.getOrDefault(boxSn, 0L);
+
+ // 检查与上次处理时间的间隔
+ if (currentTime - lastTelemetryTime >= 1000) { // 1秒
+ TelemetryData telemetryData = UavTelemetryDataConverter.convertProtoToEntity(uavTelemetryDataCmd.getTelemetryData());
+ UavTelemetryDataCache.putUavTelemetryData(telemetryData);
+ logPrint("无人机遥测", telemetryData.getBoxSn());
+
+ // 更新最后处理时间
+ lastTelemetryTimes.put(boxSn, currentTime);
+ } else {
+ log.debug("无人机 " + boxSn + " 遥测数据接收过于频繁,已跳过处理");
+ }
break;
+
case (byte) 0x0C:
// 处理无人机信道质量数据
SignalInfoCmd signalInfoCmd = (SignalInfoCmd) tyCommand;
@@ -524,7 +528,7 @@
break;
default:
// 处理其他消息
- log.debug("收到其他消息-->其他消息");
+ log.warn("收到其他消息-->{}", tyCommand.getCmdCode());
}
}
@@ -537,7 +541,7 @@
private void logPrint(String message, byte result, Integer errorCode) {
log.info("收到{}回复:{} 错误码:{}【{}】",
message,
- String.format("0x%02X", result & 0xFF),
+ ByteUtils.byteToHex(result),
errorCode,
ErrorCodeEnum.getDescByCode(errorCode));
}
@@ -552,4 +556,25 @@
HeartbeatCmd heartbeatMessage = new HeartbeatCmd(timestamp);
this.sendMessage(tyConfiguration.getIpPort(), heartbeatMessage);
}
+
+ /**
+ * 发送消息
+ */
+ private void sendMessage(String key, BaseCmd msg) {
+ try {
+ ChannelFuture future = TyNettyTcpClient.channels.get(key).getChannelFuture();
+ Channel channel = future.channel();
+ if (channel.isActive()) {
+ InetSocketAddress ipSocket = (InetSocketAddress) channel.remoteAddress();
+ String host = ipSocket.getHostString();
+ int port = ipSocket.getPort();
+ channel.writeAndFlush(msg); // 发送编码后的数据
+ log.debug("向天宇服务器【{}:{}】发送数据,命令码:{}", host, port, String.format("0x%02X", msg.getCmdCode() & 0xFF));
+ } else {
+ log.error("与天宇服务器链接断开,无法发送数据!");
+ }
+ } catch (Exception e) {
+ log.error("发送消息异常:{}", e.getMessage());
+ }
+ }
}
\ No newline at end of file
--
Gitblit v1.9.3