From a7b3fa2ee28c19567e8186a35de75fba51bccc96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B0=8F=E4=BA=91?= Date: Wed, 28 Jan 2026 14:13:45 +0800 Subject: [PATCH] xx --- .../device/domain/impl/djimqtt/README.md | 202 ++++++++++++++++++ .../config/DjiMqttProperties.java | 2 +- .../ruoyi/device/service/impl/DjiService.java | 70 ++++++ 3 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md rename src/main/java/com/ruoyi/device/{domain/impl/djimqtt => service}/config/DjiMqttProperties.java (95%) create mode 100644 src/main/java/com/ruoyi/device/service/impl/DjiService.java diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md new file mode 100644 index 0000000..1798220 --- /dev/null +++ b/src/main/java/com/ruoyi/device/domain/impl/djimqtt/README.md @@ -0,0 +1,202 @@ +# DJI MQTT 模块使用说明(支持多客户端) + +## 概述 + +本模块实现了大疆MQTT消息的接收和处理功能,支持动态创建多个MQTT客户端,每个客户端可以连接到不同的服务器。 + +## 核心特性 + +✅ **多客户端支持** - 可以同时创建多个MQTT客户端 +✅ **动态配置** - 每个客户端可以独立配置IP、端口、用户名等 +✅ **独立消息处理** - 每个客户端有独立的消息处理器 +✅ **共享订阅可选** - 支持开启/关闭共享订阅 +✅ **完整数据模型** - 包含所有无人机和机场字段 +✅ **自动区分设备** - 自动识别无人机和机场数据 + +## 架构设计 + +``` +DjiMqttClientManager (管理器) + ↓ +DjiMqttClientService (客户端实例) + ↓ +DjiMqttMessageHandler (消息处理器) + ↓ +IDroneDataCallback / IDockDataCallback (回调接口) +``` + +## 快速开始 + +### 1. 注入管理器 + +```java +@Autowired +private DjiMqttClientManager clientManager; +``` + +### 2. 创建客户端 + +```java +// 构建配置 +DjiMqttClientConfig config = DjiMqttClientConfig.builder() + .host("mqtt.t-aaron.com") // MQTT服务器地址 + .port(10883) // 端口 + .clientId("my_client_1") // 客户端ID(必须唯一) + .username("admin") // 用户名 + .password("admin") // 密码 + .useSharedSubscription(true) // 是否使用共享订阅 + .sharedGroupName("dji-group") // 共享订阅组名 + .build(); + +// 创建并连接客户端 +String clientId = clientManager.createClient(config); +``` + +### 3. 注册回调 + +```java +// 获取消息处理器 +DjiMqttMessageHandler handler = clientManager.getHandler(clientId); + +// 注册无人机数据回调 +handler.registerDroneDataCallback(droneData -> { + System.out.println("无人机SN: " + droneData.getDeviceSn()); + System.out.println("位置: " + droneData.getLatitude() + ", " + droneData.getLongitude()); +}); + +// 注册机场数据回调 +handler.registerDockDataCallback(dockData -> { + System.out.println("机场SN: " + dockData.getDeviceSn()); + System.out.println("温度: " + dockData.getTemperature()); +}); +``` + +## 多客户端示例 + +### 场景:同时连接多个MQTT服务器 + +```java +@Component +public class MyMqttService { + + @Autowired + private DjiMqttClientManager clientManager; + + public void init() { + // 客户端1:连接到服务器A + DjiMqttClientConfig config1 = DjiMqttClientConfig.builder() + .host("mqtt.server-a.com") + .port(10883) + .clientId("client_a") + .username("admin") + .password("admin") + .useSharedSubscription(true) + .build(); + + String clientId1 = clientManager.createClient(config1); + DjiMqttMessageHandler handler1 = clientManager.getHandler(clientId1); + handler1.registerDroneDataCallback(data -> processServerA(data)); + + // 客户端2:连接到服务器B + DjiMqttClientConfig config2 = DjiMqttClientConfig.builder() + .host("mqtt.server-b.com") + .port(1883) + .clientId("client_b") + .username("user2") + .password("pass2") + .useSharedSubscription(false) + .build(); + + String clientId2 = clientManager.createClient(config2); + DjiMqttMessageHandler handler2 = clientManager.getHandler(clientId2); + handler2.registerDroneDataCallback(data -> processServerB(data)); + } +} +``` + +## 管理器API + +### 创建客户端 +```java +String clientId = clientManager.createClient(config); +``` + +### 获取消息处理器 +```java +DjiMqttMessageHandler handler = clientManager.getHandler(clientId); +``` + +### 获取客户端 +```java +DjiMqttClientService client = clientManager.getClient(clientId); +boolean isConnected = client.isConnected(); +``` + +### 移除客户端 +```java +clientManager.removeClient(clientId); +``` + +### 断开所有客户端 +```java +clientManager.disconnectAll(); +``` + +### 获取所有客户端ID +```java +Set clientIds = clientManager.getAllClientIds(); +``` + +## 配置参数说明 + +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| host | String | 是 | - | MQTT服务器地址 | +| port | Integer | 是 | - | MQTT服务器端口 | +| clientId | String | 是 | - | 客户端ID(必须唯一) | +| username | String | 是 | - | 用户名 | +| password | String | 是 | - | 密码 | +| connectionTimeout | Integer | 否 | 30 | 连接超时时间(秒) | +| keepAliveInterval | Integer | 否 | 60 | 保持连接时间(秒) | +| autoReconnect | Boolean | 否 | true | 自动重连 | +| cleanSession | Boolean | 否 | false | 清除会话 | +| useSharedSubscription | Boolean | 否 | true | 是否使用共享订阅 | +| sharedGroupName | String | 否 | dji-group | 共享订阅组名 | + +## 数据模型 + +### DroneData(无人机数据) + +包含100+字段,主要分类: +- **基础信息**:固件版本、飞行器状态、档位等 +- **位置信息**:经纬度、高度、Home点等 +- **姿态信息**:偏航角、横滚角、俯仰角 +- **速度信息**:水平速度、垂直速度、风速 +- **电池信息**:电量、剩余飞行时间、电池详情 +- **相机信息**:拍照录像状态、变焦、红外测温等 +- **避障信息**:水平/上视/下视避障状态 +- **保养信息**:保养状态、累计飞行时间/架次 + +### DockData(机场数据) + +包含60+字段,主要分类: +- **基础信息**:固件版本、机场状态、任务状态 +- **位置信息**:经纬度、高度、朝向角 +- **环境信息**:温度、湿度、风速、降雨量 +- **设备状态**:舱盖状态、飞行器在舱状态、补光灯等 +- **电池信息**:充电状态、备用电池、电池保养 +- **网络信息**:网络类型、质量、速率 +- **图传信息**:4G/SDR链路状态、信号质量 + +## 注意事项 + +1. **clientId必须唯一**:每个MQTT客户端的clientId必须全局唯一 +2. **部分字段推送**:每次MQTT消息可能只包含部分字段,使用时需要判空 +3. **原始数据访问**:所有字段都保存在`rawData`中,可以通过Map访问 +4. **共享订阅**:多实例部署时建议开启共享订阅,避免重复消费 +5. **独立处理器**:每个客户端有独立的消息处理器,互不影响 +6. **自动重连**:连接断开后会自动重连(可配置) + +## 完整示例 + +参考 `DjiMqttUsageExample.java` 获取完整示例代码。 diff --git a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/config/DjiMqttProperties.java b/src/main/java/com/ruoyi/device/service/config/DjiMqttProperties.java similarity index 95% rename from src/main/java/com/ruoyi/device/domain/impl/djimqtt/config/DjiMqttProperties.java rename to src/main/java/com/ruoyi/device/service/config/DjiMqttProperties.java index 4be0041..b318d03 100644 --- a/src/main/java/com/ruoyi/device/domain/impl/djimqtt/config/DjiMqttProperties.java +++ b/src/main/java/com/ruoyi/device/service/config/DjiMqttProperties.java @@ -1,4 +1,4 @@ -package com.ruoyi.device.domain.impl.djimqtt.config; +package com.ruoyi.device.service.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/src/main/java/com/ruoyi/device/service/impl/DjiService.java b/src/main/java/com/ruoyi/device/service/impl/DjiService.java new file mode 100644 index 0000000..b43de63 --- /dev/null +++ b/src/main/java/com/ruoyi/device/service/impl/DjiService.java @@ -0,0 +1,70 @@ +package com.ruoyi.device.service.impl; + +import com.ruoyi.device.domain.impl.djimqtt.callback.IDockDataCallback; +import com.ruoyi.device.domain.impl.djimqtt.callback.IDroneDataCallback; +import com.ruoyi.device.domain.impl.djimqtt.config.DjiMqttClientConfig; +import com.ruoyi.device.service.config.DjiMqttProperties; +import com.ruoyi.device.domain.impl.djimqtt.handler.DjiMqttMessageHandler; +import com.ruoyi.device.domain.impl.djimqtt.manager.DjiMqttClientManager; +import com.ruoyi.device.domain.impl.djimqtt.model.DockData; +import com.ruoyi.device.domain.impl.djimqtt.model.DroneData; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class DjiService { + + @Autowired + private DjiMqttClientManager clientManager; + + @Autowired + private DjiMqttProperties mqttProperties; + + @EventListener(ApplicationReadyEvent.class) + public void onApplicationReady() { + + // 从配置文件读取配置 + DjiMqttClientConfig config = DjiMqttClientConfig.builder() + .host(mqttProperties.getHost()) + .port(mqttProperties.getPort()) + .clientId(mqttProperties.getClientId()) + .username(mqttProperties.getUsername()) + .password(mqttProperties.getPassword()) + .connectionTimeout(mqttProperties.getConnectionTimeout()) + .keepAliveInterval(mqttProperties.getKeepAliveInterval()) + .autoReconnect(mqttProperties.getAutoReconnect()) + .cleanSession(mqttProperties.getCleanSession()) + .useSharedSubscription(true) + .sharedGroupName("dji-group") + .build(); + + // 创建客户端 + String clientId = clientManager.createClient(config); + + // 获取消息处理器 + DjiMqttMessageHandler handler = clientManager.getHandler(clientId); + + // 注册无人机数据回调 + handler.registerDroneDataCallback(new IDroneDataCallback() { + @Override + public void onDroneData(DroneData droneData) { + log.info("droneData:{}", droneData); + } + }); + + // 注册机场数据回调 + handler.registerDockDataCallback(new IDockDataCallback() { + @Override + public void onDockData(DockData dockData) { + log.info("droneData:{}", dockData); + } + }); + + log.info("客户端已创建并注册回调"); + } + +}