一次大的提交
This commit is contained in:
296
docs/DRONE_STATION_OSD_CARD_USAGE.md
Normal file
296
docs/DRONE_STATION_OSD_CARD_USAGE.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# 无人机机场 OSD 实时数据展示功能
|
||||
|
||||
## 📋 功能概述
|
||||
|
||||
在无人机机场详情页面添加了 **OSD 实时数据卡片**,通过 MQTT 订阅 `thing/product/${gatewaySn}/osd` topic,实时展示机场的遥测数据。
|
||||
|
||||
## 🎯 核心特性
|
||||
|
||||
### 1. 滑动窗口设计
|
||||
- **左右滑动切换**:用户可以左右滑动查看不同的 OSD 数据字段
|
||||
- **底部指示器**:显示当前页码和总页数
|
||||
- **滑动提示**:左右箭头提示用户可以滑动
|
||||
|
||||
### 2. 智能状态管理
|
||||
- **在线时**:显示实时 OSD 数据(电量、温度、风速等)
|
||||
- **离线时**:显示"机场离线,暂无实时数据"提示
|
||||
- **加载中**:显示加载动画
|
||||
|
||||
### 3. 数据字段展示
|
||||
|
||||
目前展示的 OSD 字段包括:
|
||||
|
||||
| 字段 | 图标 | 颜色规则 | 示例值 |
|
||||
|------|------|---------|--------|
|
||||
| 电量 | 🔋 battery_full | >50% 绿色, 20-50% 橙色, <20% 红色 | 85% |
|
||||
| 温度 | 🌡️ thermostat | 蓝色 | 25°C |
|
||||
| 风速 | 💨 air | 绿色 | 3.5 m/s |
|
||||
| 降雨量 | 💧 water_drop | 蓝色 | 小雨 / 12 mm |
|
||||
| 网络状态 | 📶 network_check | 灰色 | 等级 4 |
|
||||
| GPS | 🛰️ gps_fixed | 紫色 | 12 颗 |
|
||||
|
||||
## 📁 文件结构
|
||||
|
||||
```
|
||||
lib/features/v2/device_list/
|
||||
├── presentation/
|
||||
│ ├── pages/
|
||||
│ │ └── drone_station_detail_page.dart # 详情页(集成 OSD 卡片)
|
||||
│ └── widgets/
|
||||
│ └── drone_station_osd_card.dart # OSD 实时数据卡片组件
|
||||
```
|
||||
|
||||
## 🔧 技术实现
|
||||
|
||||
### 1. MQTT 数据订阅
|
||||
|
||||
```dart
|
||||
// 订阅机场 OSD topic
|
||||
final stationTopic = 'thing/product/$gatewaySn/osd';
|
||||
|
||||
// 监听数据流
|
||||
_subscription = _dataSource.stationOsdStream.listen((osd) {
|
||||
setState(() {
|
||||
_currentOsd = osd;
|
||||
_parseOsdFields(osd); // 解析并更新 UI
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 数据解析
|
||||
|
||||
```dart
|
||||
void _parseOsdFields(DroneOsdEntity osd) {
|
||||
final data = osd.rawData;
|
||||
|
||||
_osdFields = [
|
||||
{
|
||||
'icon': Icons.battery_full_rounded,
|
||||
'label': '电量',
|
||||
'value': data['battery'] != null ? '${data['battery']}%' : '未知',
|
||||
'color': _getBatteryColor(data['battery']),
|
||||
},
|
||||
// ... 其他字段
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 滑动卡片实现
|
||||
|
||||
使用 `PageView.builder` 实现左右滑动:
|
||||
|
||||
```dart
|
||||
PageView.builder(
|
||||
itemCount: _osdFields.length,
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
final field = _osdFields[index];
|
||||
return _buildOsdPage(field, index);
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
## 🎨 UI 设计
|
||||
|
||||
### 卡片布局
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ [图标] 电量 ◀ ▶ │
|
||||
│ │
|
||||
│ 85% │
|
||||
│ │
|
||||
│ 1 / 6 │
|
||||
│ │
|
||||
│ ● ○ ○ ○ ○ ○ │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
### 状态指示器
|
||||
- **当前页**:长条蓝色圆点(16px)
|
||||
- **其他页**:短条灰色圆点(6px)
|
||||
|
||||
## 📊 数据映射规则
|
||||
|
||||
### 降雨量格式化
|
||||
|
||||
```dart
|
||||
String _formatRainfall(dynamic rainfall) {
|
||||
if (rainfall is String) {
|
||||
switch (rainfall.toLowerCase()) {
|
||||
case 'no_rain': return '无降雨';
|
||||
case 'light_rain': return '小雨';
|
||||
case 'moderate_rain': return '中雨';
|
||||
case 'heavy_rain': return '大雨';
|
||||
default: return '$rainfall mm';
|
||||
}
|
||||
}
|
||||
return '$rainfall mm';
|
||||
}
|
||||
```
|
||||
|
||||
### 电量颜色规则
|
||||
|
||||
```dart
|
||||
Color _getBatteryColor(dynamic battery) {
|
||||
final value = battery is num ? battery.toDouble() : 0.0;
|
||||
if (value > 50) return Color(0xFF00B42A); // 绿色
|
||||
if (value > 20) return Color(0xFFFF7D00); // 橙色
|
||||
return Color(0xFFF53F3F); // 红色
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 生命周期管理
|
||||
|
||||
### 启动监听
|
||||
```dart
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_startListening(); // 开始监听 MQTT
|
||||
}
|
||||
```
|
||||
|
||||
### 停止监听
|
||||
```dart
|
||||
@override
|
||||
void dispose() {
|
||||
_stopListening(); // 取消订阅,释放资源
|
||||
super.dispose();
|
||||
}
|
||||
```
|
||||
|
||||
### 动态更新
|
||||
```dart
|
||||
@override
|
||||
void didUpdateWidget(DroneStationOsdCard oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
// gatewaySn 或 isOnline 变化时重新订阅
|
||||
if (oldWidget.gatewaySn != widget.gatewaySn ||
|
||||
oldWidget.isOnline != widget.isOnline) {
|
||||
_stopListening();
|
||||
_startListening();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 在详情页中集成
|
||||
|
||||
```dart
|
||||
DroneStationOsdCard(
|
||||
gatewaySn: widget.station.gatewaySn,
|
||||
isOnline: detail.isOnline,
|
||||
)
|
||||
```
|
||||
|
||||
### 参数说明
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `gatewaySn` | String | 机场网关序列号(用于 MQTT topic) |
|
||||
| `isOnline` | bool | 机场是否在线(决定是否显示实时数据) |
|
||||
|
||||
## 📝 扩展建议
|
||||
|
||||
### 1. 添加更多 OSD 字段
|
||||
|
||||
在 `_parseOsdFields` 方法中添加新字段:
|
||||
|
||||
```dart
|
||||
{
|
||||
'icon': Icons.new_icon,
|
||||
'label': '新字段名称',
|
||||
'value': data['newField'] != null ? '${data['newField']}' : '未知',
|
||||
'color': const Color(0xFF165DFF),
|
||||
},
|
||||
```
|
||||
|
||||
### 2. 自定义滑动方向
|
||||
|
||||
修改 `PageView` 的 `scrollDirection`:
|
||||
|
||||
```dart
|
||||
PageView.builder(
|
||||
scrollDirection: Axis.vertical, // 改为上下滑动
|
||||
// ...
|
||||
)
|
||||
```
|
||||
|
||||
### 3. 自动轮播
|
||||
|
||||
添加定时器自动切换卡片:
|
||||
|
||||
```dart
|
||||
Timer.periodic(Duration(seconds: 3), (timer) {
|
||||
if (_osdFields.isNotEmpty) {
|
||||
setState(() {
|
||||
_currentIndex = (_currentIndex + 1) % _osdFields.length;
|
||||
});
|
||||
_pageController.animateToPage(_currentIndex, ...);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 4. 手势优化
|
||||
|
||||
添加双击放大、长按复制等功能:
|
||||
|
||||
```dart
|
||||
GestureDetector(
|
||||
onDoubleTap: () {
|
||||
// 双击放大
|
||||
},
|
||||
onLongPress: () {
|
||||
// 长按复制数值
|
||||
Clipboard.setData(ClipboardData(text: field['value']));
|
||||
},
|
||||
child: _buildOsdPage(field, index),
|
||||
)
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **MQTT 连接**:确保应用已连接到 MQTT 服务器
|
||||
2. **topic 格式**:必须为 `thing/product/${gatewaySn}/osd`
|
||||
3. **数据格式**:MQTT 消息 payload 必须是 JSON 格式
|
||||
4. **内存管理**:页面销毁时必须取消订阅,避免内存泄漏
|
||||
5. **在线判断**:只有机场在线时才订阅 MQTT,离线时不订阅
|
||||
|
||||
## 🐛 调试技巧
|
||||
|
||||
### 查看 MQTT 日志
|
||||
|
||||
```dart
|
||||
debugPrint('🔊 [DroneStationOsdCard] 开始监听机场 OSD: ${widget.gatewaySn}');
|
||||
debugPrint('✅ [DroneStationOsdCard] 收到机场 OSD 数据');
|
||||
```
|
||||
|
||||
### 检查数据解析
|
||||
|
||||
```dart
|
||||
debugPrint('📊 [DroneStationOsdCard] OSD 原始数据: ${osd.rawData}');
|
||||
debugPrint('📊 [DroneStationOsdCard] 解析后字段数: ${_osdFields.length}');
|
||||
```
|
||||
|
||||
## 📦 依赖项
|
||||
|
||||
- `flutter_bloc`: 状态管理
|
||||
- `mqtt_client`: MQTT 通信
|
||||
- `equatable`: 实体类比较
|
||||
- `get_it`: 依赖注入
|
||||
|
||||
## ✅ 完成清单
|
||||
|
||||
- [x] 创建 `DroneStationOsdCard` 组件
|
||||
- [x] 实现 MQTT 数据订阅
|
||||
- [x] 实现滑动窗口 UI
|
||||
- [x] 实现数据解析和格式化
|
||||
- [x] 集成到详情页
|
||||
- [x] 添加状态管理(在线/离线/加载中)
|
||||
- [x] 添加生命周期管理
|
||||
- [x] 添加调试日志
|
||||
Reference in New Issue
Block a user