From c5551fc0fb643f85aafeb6827687af4df88bd1f7 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Fri, 01 Nov 2024 10:29:53 +0800
Subject: [PATCH] 增加:喊话器

---
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RealSpeakDTO.java           |   21 +
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/VolumeSettingDTO.java       |   23 ++
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/TextSpeakCmd.java       |   40 +++
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/LoopSettingDTO.java         |   23 ++
 ard-work/src/main/java/com/ard/tianyu/service/impl/TyServiceImpl.java               |   66 ++++++
 ard-work/src/main/java/com/ard/tianyu/service/ITyService.java                       |   36 +++
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/StopSpeakCmd.java       |   35 +++
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RecordSpeakCmd.java     |   36 +++
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/SpeakModeSwitchDTO.java     |   23 ++
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RecordSpeakDTO.java         |   21 +
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/LoopSettingCmd.java     |   35 +++
 README.md                                                                           |   68 -----
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/StopSpeakDTO.java           |   20 +
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/SpeakModeSwitchCmd.java |   36 +++
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RealSpeakCmd.java       |   36 +++
 ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/TextSpeakDTO.java           |   27 ++
 ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/VolumeSettingCmd.java   |   35 +++
 ard-work/src/main/java/com/ard/tianyu/controller/UavSpeakerController.java          |   49 ++++
 18 files changed, 571 insertions(+), 59 deletions(-)

diff --git a/README.md b/README.md
index e5a47b8..3531bb7 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,18 @@
-<p align="center">
-	<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
-</p>
-<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.8</h1>
+
+<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">ARD-UAV v3.8.8</h1>
 <h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
-<p align="center">
-	<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
-	<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.8-brightgreen.svg"></a>
-	<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
-</p>
+
 
 ## 平台简介
 
-若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
+这是一套基于天宇协议的无人机平台。
 
 * 前端采用Vue、Element UI。
 * 后端采用Spring Boot、Spring Security、Redis & Jwt。
 * 权限认证使用Jwt,支持多终端认证系统。
 * 支持加载动态权限菜单,多方式轻松权限控制。
 * 高效率开发,使用代码生成器可以一键生成前后端代码。
-* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
-* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
-* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
-* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
-* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
+
 
 ## 内置功能
 
@@ -45,52 +35,12 @@
 17. 在线构建器:拖动表单元素生成相应的HTML代码。
 18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
 
-## 在线体验
+## 前端登录
 
-- admin/admin123  
-- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
+- admin/admin123
 
-演示地址:http://vue.ruoyi.vip  
-文档地址:http://doc.ruoyi.vip
-
-## 演示图
-
-<table>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
-    </tr>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
-    </tr>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
-    </tr>
-	<tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
-    </tr>	 
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
-    </tr>
-	<tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
-    </tr>
-	<tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
-    </tr>
-    <tr>
-        <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
-        <td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
-    </tr>
-</table>
+后台地址:http://localhost:80
+接口地址:http://localhost:8080/doc.html
 
 
-## 若依前后端分离交流群
 
-QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) 点击按钮入群。
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/controller/UavSpeakerController.java b/ard-work/src/main/java/com/ard/tianyu/controller/UavSpeakerController.java
new file mode 100644
index 0000000..b8960ea
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/controller/UavSpeakerController.java
@@ -0,0 +1,49 @@
+package com.ard.tianyu.controller;
+
+import com.ard.common.core.domain.AjaxResult;
+import com.ard.tianyu.model.dto.signal.SignalInfo;
+import com.ard.tianyu.model.dto.speaker.SpeakModeSwitchDTO;
+import com.ard.tianyu.model.dto.speaker.StopSpeakDTO;
+import com.ard.tianyu.model.dto.speaker.TextSpeakDTO;
+import com.ard.tianyu.model.dto.state.UavState;
+import com.ard.tianyu.model.dto.telemetry.TelemetryData;
+import com.ard.tianyu.service.ITyService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+/**
+ * UavSpeakerController
+ *
+ * @author liusuyi
+ * @date 2024年10月21日13:52
+ **/
+@Api(tags = "无人机喊话器接口")
+@RequestMapping("/uav/speaker")
+@RestController
+public class UavSpeakerController {
+
+    @Resource
+    private ITyService tyService;
+
+    @ApiOperation("喊话模式切换")
+    @PostMapping("/speakModeSwitch")
+    public AjaxResult speakModeSwitch(@RequestBody SpeakModeSwitchDTO speakModeSwitchDTO) {
+        tyService.speakModeSwitch(speakModeSwitchDTO);
+        return AjaxResult.success();
+    }
+    @ApiOperation("文字喊话")
+    @PostMapping("/textSpeak")
+    public AjaxResult textSpeak(@RequestBody TextSpeakDTO textSpeakDTO) {
+        tyService.textSpeak(textSpeakDTO);
+        return AjaxResult.success();
+    }
+    @ApiOperation("停止喊话")
+    @PostMapping("/stopSpeak")
+    public AjaxResult stopSpeak(@RequestBody StopSpeakDTO stopSpeakDTO) {
+        tyService.stopSpeak(stopSpeakDTO);
+        return AjaxResult.success();
+    }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/LoopSettingDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/LoopSettingDTO.java
new file mode 100644
index 0000000..f21f355
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/LoopSettingDTO.java
@@ -0,0 +1,23 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 设置循环播放实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class LoopSettingDTO {
+    private String boxSn;
+
+    //0x00-关,0x01-开
+    private byte actionParam;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RealSpeakDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RealSpeakDTO.java
new file mode 100644
index 0000000..84daa58
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RealSpeakDTO.java
@@ -0,0 +1,21 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 实时喊话实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RealSpeakDTO {
+    private String boxSn;
+    private byte[] data;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RecordSpeakDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RecordSpeakDTO.java
new file mode 100644
index 0000000..74970e2
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/RecordSpeakDTO.java
@@ -0,0 +1,21 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 录音喊话实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RecordSpeakDTO {
+    private String boxSn;
+    private byte[] data;
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/SpeakModeSwitchDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/SpeakModeSwitchDTO.java
new file mode 100644
index 0000000..24a3305
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/SpeakModeSwitchDTO.java
@@ -0,0 +1,23 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 喊话模式切换实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class SpeakModeSwitchDTO {
+    private String boxSn;
+
+    //0x00-文字喊话,0x01-音频喊话
+    private byte actionParam;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/StopSpeakDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/StopSpeakDTO.java
new file mode 100644
index 0000000..62e0dec
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/StopSpeakDTO.java
@@ -0,0 +1,20 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 停止喊话实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class StopSpeakDTO {
+    private String boxSn;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/TextSpeakDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/TextSpeakDTO.java
new file mode 100644
index 0000000..4408617
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/TextSpeakDTO.java
@@ -0,0 +1,27 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 文字喊话实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TextSpeakDTO {
+    private String boxSn;
+
+    //0x01~0x64
+    private byte speechRate;
+    //0x00-男生,0x01-女生,0x02-英文男声,0x03-英文女声
+    private byte voiceType;
+
+    private String TextData;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/VolumeSettingDTO.java b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/VolumeSettingDTO.java
new file mode 100644
index 0000000..41f3a22
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/model/dto/speaker/VolumeSettingDTO.java
@@ -0,0 +1,23 @@
+package com.ard.tianyu.model.dto.speaker;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 设置音量实体对象
+ *
+ * @author liusuyi
+ * @date 2024年10月26日9:02
+ **/
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class VolumeSettingDTO {
+    private String boxSn;
+
+    //0x00-文字喊话,0x01-音频喊话
+    private byte actionParam;
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/LoopSettingCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/LoopSettingCmd.java
new file mode 100644
index 0000000..e1b49c7
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/LoopSettingCmd.java
@@ -0,0 +1,35 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.speaker.LoopSettingDTO;
+import com.ard.tianyu.model.dto.speaker.VolumeSettingDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 设置循环播放指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class LoopSettingCmd extends BaseCmd {
+
+    private final byte actionParam;         //动作参数
+
+    public LoopSettingCmd(LoopSettingDTO loopSettingDTO) {
+        setDataHeader((short) 0x7479);
+        setDataLength((short) 19);
+        setBoxSn(loopSettingDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+        this.actionParam = loopSettingDTO.getActionParam();
+    }
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());    // 写入数据头
+        out.writeShort(getDataLength());    // 写入数据长度
+        out.writeBytes(getBoxSn());         // 写入盒子SN
+        out.writeByte(getCmdCode());        // 写入命令码
+        out.writeByte(0x00);          // 写入加密标志
+        out.writeByte(0x06);          // 写入动作编号
+        out.writeByte(this.actionParam);    // 写入动作参数
+    }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RealSpeakCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RealSpeakCmd.java
new file mode 100644
index 0000000..8d3c784
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RealSpeakCmd.java
@@ -0,0 +1,36 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.speaker.RealSpeakDTO;
+import com.ard.tianyu.model.dto.speaker.TextSpeakDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 实时喊话指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class RealSpeakCmd extends BaseCmd {
+
+    private final byte[] data;
+
+    public RealSpeakCmd(RealSpeakDTO realSpeakDTO) {
+
+        this.data = realSpeakDTO.getData();
+        setDataHeader((short) 0x7479);
+        setDataLength((short) (18 + this.data.length));
+        setBoxSn(realSpeakDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+    }
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());            // 写入数据头
+        out.writeShort(getDataLength());            // 写入数据长度
+        out.writeBytes(getBoxSn());                 // 写入盒子SN
+        out.writeByte(getCmdCode());                // 写入命令码
+        out.writeByte(0x00);                  // 写入加密标志
+        out.writeByte(0x02);                  // 写入动作编号
+        out.writeBytes(this.data);                  // 写入文本数据
+    }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RecordSpeakCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RecordSpeakCmd.java
new file mode 100644
index 0000000..26b3eac
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/RecordSpeakCmd.java
@@ -0,0 +1,36 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.speaker.RealSpeakDTO;
+import com.ard.tianyu.model.dto.speaker.RecordSpeakDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 录音喊话指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class RecordSpeakCmd extends BaseCmd {
+
+    private final byte[] data;
+
+    public RecordSpeakCmd(RecordSpeakDTO recordSpeakDTO) {
+
+        this.data = recordSpeakDTO.getData();
+        setDataHeader((short) 0x7479);
+        setDataLength((short) (18 + this.data.length));
+        setBoxSn(recordSpeakDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+    }
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());            // 写入数据头
+        out.writeShort(getDataLength());            // 写入数据长度
+        out.writeBytes(getBoxSn());                 // 写入盒子SN
+        out.writeByte(getCmdCode());                // 写入命令码
+        out.writeByte(0x00);                  // 写入加密标志
+        out.writeByte(0x03);                  // 写入动作编号
+        out.writeBytes(this.data);                  // 写入文本数据
+    }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/SpeakModeSwitchCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/SpeakModeSwitchCmd.java
new file mode 100644
index 0000000..315d089
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/SpeakModeSwitchCmd.java
@@ -0,0 +1,36 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.manual.EmeragencyBrakeDTO;
+import com.ard.tianyu.model.dto.speaker.SpeakModeSwitchDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 喊话模式切换指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class SpeakModeSwitchCmd extends BaseCmd {
+
+    private final byte actionParam;         //动作参数
+
+    public SpeakModeSwitchCmd(SpeakModeSwitchDTO speakModeSwitchDTO) {
+        setDataHeader((short) 0x7479);
+        setDataLength((short) 19);
+        setBoxSn(speakModeSwitchDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+        this.actionParam = speakModeSwitchDTO.getActionParam();
+    }
+
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());    // 写入数据头
+        out.writeShort(getDataLength());    // 写入数据长度
+        out.writeBytes(getBoxSn());         // 写入盒子SN
+        out.writeByte(getCmdCode());        // 写入命令码
+        out.writeByte(0x00);          // 写入加密标志
+        out.writeByte(0x01);          // 写入动作编号
+        out.writeByte(this.actionParam);    // 写入动作参数
+    }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/StopSpeakCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/StopSpeakCmd.java
new file mode 100644
index 0000000..7e5bb79
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/StopSpeakCmd.java
@@ -0,0 +1,35 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.speaker.RealSpeakDTO;
+import com.ard.tianyu.model.dto.speaker.StopSpeakDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 停止喊话指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class StopSpeakCmd extends BaseCmd {
+
+
+
+    public StopSpeakCmd(StopSpeakDTO stopSpeakDTO) {
+
+        setDataHeader((short) 0x7479);
+        setDataLength((short) 18);
+        setBoxSn(stopSpeakDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+    }
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());            // 写入数据头
+        out.writeShort(getDataLength());            // 写入数据长度
+        out.writeBytes(getBoxSn());                 // 写入盒子SN
+        out.writeByte(getCmdCode());                // 写入命令码
+        out.writeByte(0x00);                  // 写入加密标志
+        out.writeByte(0x02);                  // 写入动作编号
+        out.writeByte(0xFF);                  // 写入文本数据
+    }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/TextSpeakCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/TextSpeakCmd.java
new file mode 100644
index 0000000..b00e249
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/TextSpeakCmd.java
@@ -0,0 +1,40 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.speaker.TextSpeakDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 文字喊话指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class TextSpeakCmd extends BaseCmd {
+
+    private final byte speechRate;
+    private final byte voiceType;
+    private final String textData;
+
+    public TextSpeakCmd(TextSpeakDTO textSpeakDTO) {
+        this.speechRate = textSpeakDTO.getSpeechRate();
+        this.voiceType = textSpeakDTO.getVoiceType();
+        this.textData = textSpeakDTO.getTextData();
+        setDataHeader((short) 0x7479);
+        setDataLength((short) (20 + this.textData.getBytes().length));
+        setBoxSn(textSpeakDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+    }
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());            // 写入数据头
+        out.writeShort(getDataLength());            // 写入数据长度
+        out.writeBytes(getBoxSn());                 // 写入盒子SN
+        out.writeByte(getCmdCode());                // 写入命令码
+        out.writeByte(0x00);                  // 写入加密标志
+        out.writeByte(0x04);                  // 写入动作编号
+        out.writeByte(this.speechRate);             // 写入语速设置
+        out.writeByte(this.voiceType);              // 写入声音
+        out.writeBytes(this.textData.getBytes());   // 写入文本数据
+    }
+}
diff --git a/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/VolumeSettingCmd.java b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/VolumeSettingCmd.java
new file mode 100644
index 0000000..2bcc304
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/tianyu/netty/command/speaker/VolumeSettingCmd.java
@@ -0,0 +1,35 @@
+package com.ard.tianyu.netty.command.speaker;
+
+import com.ard.tianyu.model.dto.speaker.SpeakModeSwitchDTO;
+import com.ard.tianyu.model.dto.speaker.VolumeSettingDTO;
+import com.ard.tianyu.netty.command.BaseCmd;
+import io.netty.buffer.ByteBuf;
+
+/**
+ * 设置音量指令
+ *
+ * @author liusuyi
+ * @date 2024年10月30日16:20
+ **/
+public class VolumeSettingCmd extends BaseCmd {
+
+    private final byte actionParam;         //动作参数
+
+    public VolumeSettingCmd(VolumeSettingDTO volumeSettingDTO) {
+        setDataHeader((short) 0x7479);
+        setDataLength((short) 19);
+        setBoxSn(volumeSettingDTO.getBoxSn().getBytes());
+        setCmdCode((byte) 0xD3);
+        this.actionParam = volumeSettingDTO.getActionParam();
+    }
+
+    public void encode(ByteBuf out) {
+        out.writeShort(getDataHeader());    // 写入数据头
+        out.writeShort(getDataLength());    // 写入数据长度
+        out.writeBytes(getBoxSn());         // 写入盒子SN
+        out.writeByte(getCmdCode());        // 写入命令码
+        out.writeByte(0x00);          // 写入加密标志
+        out.writeByte(0x05);          // 写入动作编号
+        out.writeByte(this.actionParam);    // 写入动作参数
+    }
+}
\ No newline at end of file
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 c4f9e4c..acac701 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
@@ -9,6 +9,7 @@
 import com.ard.tianyu.model.dto.control.SpeedControlDTO;
 import com.ard.tianyu.model.dto.manual.*;
 import com.ard.tianyu.model.dto.signal.SignalInfo;
+import com.ard.tianyu.model.dto.speaker.*;
 import com.ard.tianyu.model.dto.state.UavState;
 import com.ard.tianyu.model.dto.telemetry.TelemetryData;
 import com.ard.tianyu.model.receiver.*;
@@ -193,6 +194,41 @@
     SignalInfo getSignalInfo(String boxSn);
 
     /**
+     * 喊话模式切换
+     */
+    void speakModeSwitch(SpeakModeSwitchDTO speakModeSwitchDTO);
+
+    /**
+     * 文字喊话
+     */
+    void textSpeak(TextSpeakDTO textSpeakDTO);
+
+    /**
+     * 实时喊话
+     */
+    void realSpeak(RealSpeakDTO realSpeakDTO);
+
+    /**
+     * 录音喊话
+     */
+    void recordSpeak(RecordSpeakDTO recordSpeakDTO);
+
+    /**
+     * 设置音量
+     */
+    void volumeSetting(VolumeSettingDTO volumeSettingDTO);
+
+    /**
+     * 设置循环播放
+     */
+    void loopSetting(LoopSettingDTO loopSettingDTO);
+
+    /**
+     * 停止喊话
+     */
+    void stopSpeak(StopSpeakDTO stopSpeakDTO);
+
+    /**
      * 处理回复消息
      */
     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 c5cd5b7..6d2a6f6 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
@@ -18,6 +18,7 @@
 import com.ard.tianyu.model.dto.converter.UavTelemetryDataConverter;
 import com.ard.tianyu.model.dto.manual.*;
 import com.ard.tianyu.model.dto.signal.SignalInfo;
+import com.ard.tianyu.model.dto.speaker.*;
 import com.ard.tianyu.model.dto.state.UavState;
 import com.ard.tianyu.model.dto.telemetry.TelemetryData;
 import com.ard.tianyu.model.receiver.*;
@@ -35,6 +36,7 @@
 import com.ard.tianyu.netty.command.real.UavStateCmd;
 import com.ard.tianyu.netty.command.real.UavTelemetryDataCmd;
 import com.ard.tianyu.netty.command.register.*;
+import com.ard.tianyu.netty.command.speaker.*;
 import com.ard.tianyu.netty.handler.ErrorCodeEnum;
 import com.ard.tianyu.service.ITyService;
 import com.ard.tianyu.websocket.utils.WebSocketUtil;
@@ -384,6 +386,67 @@
     }
 
     /**
+     * 喊话模式切换
+     */
+    @Override
+    public void speakModeSwitch(SpeakModeSwitchDTO speakModeSwitchDTO) {
+        SpeakModeSwitchCmd speakModeSwitchCmd = new SpeakModeSwitchCmd(speakModeSwitchDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), speakModeSwitchCmd);
+    }
+
+    /**
+     * 文字喊话
+     */
+    @Override
+    public void textSpeak(TextSpeakDTO textSpeakDTO) {
+        TextSpeakCmd textSpeakCmd = new TextSpeakCmd(textSpeakDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), textSpeakCmd);
+    }
+
+    /**
+     * 实时喊话
+     */
+    @Override
+    public void realSpeak(RealSpeakDTO realSpeakDTO) {
+        RealSpeakCmd realSpeakCmd = new RealSpeakCmd(realSpeakDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), realSpeakCmd);
+    }
+
+    /**
+     * 录音喊话
+     */
+    @Override
+    public void recordSpeak(RecordSpeakDTO recordSpeakDTO) {
+        RecordSpeakCmd recordSpeakCmd = new RecordSpeakCmd(recordSpeakDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), recordSpeakCmd);
+    }
+    /**
+     * 设置音量
+     */
+    @Override
+    public void volumeSetting(VolumeSettingDTO volumeSettingDTO) {
+        VolumeSettingCmd volumeSettingCmd = new VolumeSettingCmd(volumeSettingDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), volumeSettingCmd);
+    }
+
+    /**
+     * 设置循环播放
+     */
+    @Override
+    public void loopSetting(LoopSettingDTO loopSettingDTO) {
+        LoopSettingCmd loopSettingCmd = new LoopSettingCmd(loopSettingDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), loopSettingCmd);
+    }
+    /**
+     * 停止喊话
+     */
+    @Override
+    public void stopSpeak(StopSpeakDTO stopSpeakDTO) {
+        StopSpeakCmd stopSpeakCmd=new StopSpeakCmd(stopSpeakDTO);
+        this.sendMessage(tyConfiguration.getIpPort(), stopSpeakCmd);
+    }
+
+    /**
      * 处理天宇服务器返回的消息
      */
     @Override
@@ -427,6 +490,9 @@
             case (byte) 0xA9:
                 // 处理无人机遥测消息
                 UavTelemetryDataCmd uavTelemetryDataCmd = (UavTelemetryDataCmd) tyCommand;
+                if (uavTelemetryDataCmd.getBoxSn() == null) {
+                    return;
+                }
                 String boxSn = ByteUtils.bytesToString(uavTelemetryDataCmd.getBoxSn()); // 假设有获取无人机ID的方法
                 long currentTime = System.currentTimeMillis();
 

--
Gitblit v1.9.3