Files
flutterApp/docs/DRONE_STATION_OSD_CARD_USAGE.md
2026-08-07 08:49:29 +08:00

297 lines
6.9 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 无人机机场 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] 添加调试日志