ard-work/src/main/java/com/ard/tianyu/controller/UavController.java
@@ -69,4 +69,11 @@ Boolean state = tyService.updateBoxSettings(boxSettingsDTO); return AjaxResult.success(state); } @ApiOperation("云台转动(基于角度)") @GetMapping("/controlAngle") public AjaxResult controlAngle(String boxSn) { tyService.controlAngle(boxSn); return AjaxResult.success(); } } ard-work/src/main/java/com/ard/tianyu/netty/command/ControlAngleCommand.java
New file @@ -0,0 +1,47 @@ package com.ard.tianyu.netty.command; import io.netty.buffer.ByteBuf; import lombok.Data; /** * 云台转动(基于角度)命令 * * @author 刘苏义 * @date 2024/10/22 16:36 */ @Data public class ControlAngleCommand extends BaseCommand{ private final byte[] boxSn; // 云盒编号 private final byte encryptFlag; // 加密标志 private final byte actionId; // 动作编号 private final byte rotationAngle; // 转动角度 public ControlAngleCommand(byte[] boxSn, byte encryptFlag, byte actionId, byte rotationAngle) { if (boxSn.length != 15) { throw new IllegalArgumentException("云盒编号长度必须为15字节"); } setDataHeader((short)0x7479); setDataLength(getDataLength()); setCmdCode((byte)0xD1); this.boxSn = boxSn; this.encryptFlag = encryptFlag; this.actionId = actionId; this.rotationAngle = rotationAngle; } public short getDataLength() { // 计算数据长度: 云盒编号 + 指令编号 + 加密标志 + 动作编号 + 转动角度 return (short) (2 + 15 + 1 + 1 + 1); // 帧头 + 数据内容 } public void encode(ByteBuf out) { out.writeShort(getDataHeader()); // 写入帧头 out.writeShort(getDataLength()); // 写入数据长度 out.writeByte(getCmdCode()); // 写入指令编号 out.writeBytes(boxSn); // 写入云盒编号 out.writeByte(encryptFlag); // 写入加密标志 out.writeByte(actionId); // 写入动作编号 out.writeByte(rotationAngle); // 写入转动角度 } } ard-work/src/main/java/com/ard/tianyu/netty/command/HeartbeatCommand.java
@@ -2,7 +2,12 @@ import io.netty.buffer.ByteBuf; /** * 心跳命令 * * @author 刘苏义 * @date 2024/10/22 16:36 */ public class HeartbeatCommand extends BaseCommand { private final long timestamp; ard-work/src/main/java/com/ard/tianyu/netty/command/HeartbeatReplyCommand.java
@@ -1,10 +1,15 @@ package com.ard.tianyu.netty.command; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * 心跳回复命令 * * @author 刘苏义 * @date 2024/10/22 16:36 */ @Data @NoArgsConstructor public class HeartbeatReplyCommand extends BaseCommand { @@ -17,6 +22,7 @@ setCmdCode((byte) 0x02); // 设置指令编号 setDataLength((short) (13)); // 数据长度 (指令编号 + 时间戳) } public void encode(ByteBuf out) { out.writeShort(getDataHeader()); out.writeShort(getDataLength()); ard-work/src/main/java/com/ard/tianyu/netty/command/RegisterCommand.java
@@ -1,6 +1,13 @@ package com.ard.tianyu.netty.command;// RegisterMessage.java import io.netty.buffer.ByteBuf; /** * 注册命令 * * @author 刘苏义 * @date 2024/10/22 16:36 */ public class RegisterCommand extends BaseCommand { private int userId; private byte[] accessToken; ard-work/src/main/java/com/ard/tianyu/netty/handler/MessageProtocolDecoder.java
ard-work/src/main/java/com/ard/tianyu/service/ITyService.java
@@ -55,7 +55,10 @@ /** * 注册 * @return */ void registerMessage(); /** * 云台转动(基于角度) */ void controlAngle(String boxSn); } ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java
@@ -7,10 +7,12 @@ import com.ard.tianyu.model.dto.BoxSettingsDTO; import com.ard.tianyu.model.receiver.*; import com.ard.tianyu.netty.command.BaseCommand; import com.ard.tianyu.netty.command.ControlAngleCommand; import com.ard.tianyu.netty.command.HeartbeatCommand; import com.ard.tianyu.netty.command.RegisterCommand; import com.ard.tianyu.netty.TyNettyTcpClient; import com.ard.tianyu.service.ITyService; import com.ard.vtdu.util.ArdTool; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; @@ -104,14 +106,18 @@ return result.getState() == 1; } /** * 注册天宇平台 */ @Override public void registerMessage() { AccessTokenReceiver tyToken = tyConfiguration.getAccessToken(); RegisterCommand registerMessage = new RegisterCommand(tyToken.getCompanyId(), tyToken.getAccessToken().getBytes()); this.sendMessage(tyConfiguration.getIpPort(), registerMessage); } /** * 发送消息 */ public boolean sendMessage(String key, BaseCommand msg) { //将从用户接收的信息发送到天宇 commandCache boolean cmdResult = false; @@ -128,7 +134,7 @@ channel.writeAndFlush(buffer); // 发送编码后的数据 cmdResult = true; log.info("向天宇服务器" + host + ":" + port + "发送数据" + ",命令码:" + msg.getCmdCode()); log.info("向天宇服务器" + host + ":" + port + "发送数据" + ",命令码:" + String.format("0x%02X", msg.getCmdCode() & 0xFF)); } else { log.error("与天宇服务器链接断开,无法发送数据!"); } @@ -140,10 +146,16 @@ } } @Override public void controlAngle(String boxSn) { ControlAngleCommand controlAngleCommand = new ControlAngleCommand(boxSn.getBytes(),(byte)0x00,(byte)0x00,(byte)0x05); this.sendMessage(tyConfiguration.getIpPort(), controlAngleCommand); } @Scheduled(fixedRate = 5000) public void sendHeartBeat() { long timestamp = System.currentTimeMillis(); log.debug("定时向天宇发送⼼跳,时间戳{}", timestamp); log.info("定时向天宇发送⼼跳,时间戳{}", timestamp); HeartbeatCommand heartbeatMessage = new HeartbeatCommand(timestamp); this.sendMessage(tyConfiguration.getIpPort(), heartbeatMessage); } ard-work/src/main/java/com/ard/vtdu/service/impl/MediaServiceImpl.java
@@ -571,6 +571,9 @@ log.info("定时同步MediaMTX任务开始"); List<String> nameList = getNameList(); List<BoxReceiver> boxList = tyService.getBoxList(); if (boxList == null || boxList.isEmpty()) { return; } List<ArdVtdu> ardVtduList = boxList.stream() .filter(boxReceiver -> boxReceiver.getOnLine() != 0) // 过滤掉不在线的 .map(boxReceiver -> { ard-work/src/main/java/com/ard/vtdu/util/ArdTool.java
@@ -209,6 +209,4 @@ } } } }