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

6.9 KiB
Raw Blame History

无人机机场 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 数据订阅

// 订阅机场 OSD topic
final stationTopic = 'thing/product/$gatewaySn/osd';

// 监听数据流
_subscription = _dataSource.stationOsdStream.listen((osd) {
  setState(() {
    _currentOsd = osd;
    _parseOsdFields(osd); // 解析并更新 UI
  });
});

2. 数据解析

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 实现左右滑动:

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)

📊 数据映射规则

降雨量格式化

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';
}

电量颜色规则

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);                   // 红色
}

🔄 生命周期管理

启动监听

@override
void initState() {
  super.initState();
  _startListening(); // 开始监听 MQTT
}

停止监听

@override
void dispose() {
  _stopListening(); // 取消订阅,释放资源
  super.dispose();
}

动态更新

@override
void didUpdateWidget(DroneStationOsdCard oldWidget) {
  super.didUpdateWidget(oldWidget);
  // gatewaySn 或 isOnline 变化时重新订阅
  if (oldWidget.gatewaySn != widget.gatewaySn || 
      oldWidget.isOnline != widget.isOnline) {
    _stopListening();
    _startListening();
  }
}

🚀 使用方法

在详情页中集成

DroneStationOsdCard(
  gatewaySn: widget.station.gatewaySn,
  isOnline: detail.isOnline,
)

参数说明

参数 类型 说明
gatewaySn String 机场网关序列号(用于 MQTT topic)
isOnline bool 机场是否在线(决定是否显示实时数据)

📝 扩展建议

1. 添加更多 OSD 字段

在 _parseOsdFields 方法中添加新字段:

{
  'icon': Icons.new_icon,
  'label': '新字段名称',
  'value': data['newField'] != null ? '${data['newField']}' : '未知',
  'color': const Color(0xFF165DFF),
},

2. 自定义滑动方向

修改 PageView 的 scrollDirection:

PageView.builder(
  scrollDirection: Axis.vertical, // 改为上下滑动
  // ...
)

3. 自动轮播

添加定时器自动切换卡片:

Timer.periodic(Duration(seconds: 3), (timer) {
  if (_osdFields.isNotEmpty) {
    setState(() {
      _currentIndex = (_currentIndex + 1) % _osdFields.length;
    });
    _pageController.animateToPage(_currentIndex, ...);
  }
});

4. 手势优化

添加双击放大、长按复制等功能:

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 日志

debugPrint('🔊 [DroneStationOsdCard] 开始监听机场 OSD: ${widget.gatewaySn}');
debugPrint('✅ [DroneStationOsdCard] 收到机场 OSD 数据');

检查数据解析

debugPrint('📊 [DroneStationOsdCard] OSD 原始数据: ${osd.rawData}');
debugPrint('📊 [DroneStationOsdCard] 解析后字段数: ${_osdFields.length}');

📦 依赖项

  • flutter_bloc: 状态管理
  • mqtt_client: MQTT 通信
  • equatable: 实体类比较
  • get_it: 依赖注入

✅ 完成清单

  • 创建 DroneStationOsdCard 组件
  • 实现 MQTT 数据订阅
  • 实现滑动窗口 UI
  • 实现数据解析和格式化
  • 集成到详情页
  • 添加状态管理(在线/离线/加载中)
  • 添加生命周期管理
  • 添加调试日志