|
1 | | -# 全平台心率推送工具 |
| 1 | +# HR OSC / 心率推送 |
2 | 2 |
|
3 | | -使用 Flutter 构建的跨平台心率推送 / 监控工具,面向直播、舞台、运动监测等需要实时心率数据的场景。 |
| 3 | +一个用 Flutter 开发的跨平台 BLE 心率监控与推送工具。连接心率设备后,可将实时 BPM、在线状态与心率百分比同步到 **HTTP/WS、OSC、MQTT** 等链路,适用于直播、VRChat、舞台监测、运动记录等场景。 |
4 | 4 |
|
5 | 5 | <div align="center"> |
6 | 6 | <img src="images/logo.png" alt="HR PUSH logo" width="140" /> |
|
12 | 12 | | --- | --- | |
13 | 13 | |  |  | |
14 | 14 |
|
15 | | -## 核心功能 |
16 | | -- **BLE 扫描与过滤**:自动跳过手机/PC 广播,优先匹配包含 180D 心率服务或常见穿戴品牌关键词的设备。 |
17 | | -- **智能重连**:记忆最近成功设备,掉线自动重连;支持一键快速连接/断开。 |
18 | | -- **实时心率展示**:解析广播/特征值,显示 BPM、更新时间、信号强度(RSSI)。 |
19 | | -- **OSC / HTTP 推送**:将心率、在线状态、百分比等数据推送到本地或远端服务,默认 OSC 目标 `127.0.0.1:9000`。 |
20 | | -- **调试视图**:查看附近广播名称、RSSI、Service UUID 片段与厂家数据长度,便于排查配对问题。 |
21 | | -- **跨端一致性**:Android / iOS / Windows / macOS / Linux 统一 UI;桌面端固定竖屏窗口,方便演示与录屏。 |
| 15 | +## 主要功能 |
| 16 | +- **BLE 扫描与连接**:自动过滤无关广播,优先匹配心率服务/常见穿戴品牌;支持快速连接。 |
| 17 | +- **智能自动重连**:记忆最近成功设备;断连或心率长时间无更新时自动重连并避免并发死锁。 |
| 18 | +- **实时展示**:BPM、上次更新时间、RSSI 信号强度;RSSI 轮询间隔与“推送/刷新间隔”一致。 |
| 19 | +- **多协议推送(按需启用)** |
| 20 | + - **HTTP/WS**:填写 `http(s)://` 或 `ws(s)://` 地址后启用,发送 JSON。 |
| 21 | + - **OSC**:填写 `host:port` 后启用(留空关闭);UI 会预填推荐 `127.0.0.1:9000`。 |
| 22 | + - **MQTT**:填写 Broker 地址后启用(留空关闭);支持端口/Topic/用户名/密码/Client ID。 |
| 23 | +- **调试视图**:查看附近广播、Service UUID、RSSI、厂商数据长度,便于排查配对。 |
| 24 | +- **桌面端体验**:Windows/macOS/Linux 固定竖屏窗口;Windows 支持托盘最小化。 |
| 25 | +- **Android 常驻通知卡片**:连接后在通知栏显示当前心率并按刷新间隔更新。 |
22 | 26 |
|
23 | 27 | ## 快速开始 |
24 | | -1. 安装 Flutter 3.10+(Dart 3.10+),并启用目标平台(例如 `flutter config --enable-macos-desktop`)。 |
| 28 | +1. 安装 Flutter(>= 3.10 / Dart >= 3.10),并启用目标平台(如桌面端需 `flutter config --enable-windows-desktop`)。 |
25 | 29 | 2. 获取依赖:`flutter pub get`。 |
26 | | -3. (macOS / iOS)进入对应目录执行 `pod install` 以安装 CocoaPods 依赖。 |
27 | | -4. 连接测试设备并确保蓝牙已开启,运行:`flutter run -d <device>`。 |
| 30 | +3. 运行应用: |
| 31 | + - Android/iOS:`flutter run -d <device>` |
| 32 | + - Desktop:`flutter run -d windows|macos|linux` |
| 33 | +4. 打开应用 → 点击“重新扫描” → 选择心率设备连接。 |
28 | 34 |
|
29 | | -## 配置项速查 |
30 | | -| 配置项 | 说明 | 默认值 | |
| 35 | +## 使用说明 |
| 36 | +### 连接/重连 |
| 37 | +- “重新扫描”会刷新附近心率设备列表。 |
| 38 | +- “快速连接”会优先连接 RSSI 更好/最近出现的设备。 |
| 39 | +- 连接后若心率超过两倍失效阈值未更新,会判定掉线并自动重连。 |
| 40 | + |
| 41 | +### 推送数据格式 |
| 42 | +所有协议发送相同的 JSON payload。 |
| 43 | + |
| 44 | +- 心率事件 |
| 45 | +```json |
| 46 | +{ |
| 47 | + "event": "heartRate", |
| 48 | + "heartRate": 85, |
| 49 | + "percent": 0.42, |
| 50 | + "connected": true, |
| 51 | + "device": "Polar H10", |
| 52 | + "timestamp": "2025-12-12T09:00:00.000Z" |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +- 连接事件 |
| 57 | +```json |
| 58 | +{ |
| 59 | + "event": "connection", |
| 60 | + "connected": false, |
| 61 | + "device": "Polar H10", |
| 62 | + "timestamp": "2025-12-12T09:05:00.000Z" |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +`percent = heartRate / 最大心率`,范围 0~1。 |
| 67 | + |
| 68 | +### 配置项 |
| 69 | +| 配置项 | 说明 | 默认 | |
31 | 70 | | --- | --- | --- | |
32 | | -| HTTP/WS 推送地址 | 留空则不推送 | 空 | |
33 | | -| OSC 目标地址 | `host:port` | `127.0.0.1:9000` | |
34 | | -| OSC 路径:在线状态 | 推送设备是否在线 | `/avatar/parameters/hr_connected` | |
35 | | -| OSC 路径:当前心率 | 推送当前 BPM | `/avatar/parameters/hr_val` | |
36 | | -| OSC 路径:心率百分比 | 基于最大心率计算 | `/avatar/parameters/hr_percent` | |
37 | | -| 最大心率 | 计算百分比的分母 | `200` | |
38 | | -| 推送/刷新间隔 (ms) | 节流推送与 UI 更新 | `1000` | |
39 | | - |
40 | | -> 提示:若设备仅广播心率而不支持连接,仍可在“广播调试”视图中查看数据与信号强度。 |
41 | | -
|
42 | | -## VRChat |
43 | | -- 默认 OSC 参数插件:https://booth.pm/zh-cn/items/5531594 |
| 71 | +| HTTP/WS 推送地址 | 为空关闭;支持 `http(s)`/`ws(s)` | 空 | |
| 72 | +| OSC 目标地址 | `host:port`;为空关闭;UI 预填推荐值 | 空(推荐 `127.0.0.1:9000`) | |
| 73 | +| OSC 路径:在线状态 | 发送 bool | `/avatar/parameters/hr_connected` | |
| 74 | +| OSC 路径:当前心率 | 发送 int BPM | `/avatar/parameters/hr_val` | |
| 75 | +| OSC 路径:心率百分比 | 发送 float 0~1 | `/avatar/parameters/hr_percent` | |
| 76 | +| MQTT Broker | 为空关闭;可写 `mqtt://host:port` 或纯 host | 空 | |
| 77 | +| MQTT 端口 | Broker 未包含端口时生效 | `1883` | |
| 78 | +| MQTT Topic | 发布 JSON payload | `hr_push` | |
| 79 | +| MQTT 用户名/密码 | 可选 | 空 | |
| 80 | +| MQTT Client ID | 为空自动生成 | 空 | |
| 81 | +| 最大心率 | 用于计算百分比 | `200` | |
| 82 | +| 推送/刷新间隔 (ms) | 控制 UI 刷新、推送节流、RSSI 轮询 | `1000` | |
| 83 | + |
| 84 | +> 若设备仅广播心率不支持连接,仍可在“广播调试”视图中查看数据与信号,但推送仅在连接并订阅特征后触发。 |
| 85 | +
|
| 86 | +## VRChat(OSC) |
| 87 | +- 推荐搭配默认 OSC 参数插件:https://booth.pm/zh-cn/items/5531594 |
| 88 | +- 也可在 Avatar 参数中自行监听上述 OSC 路径。 |
| 89 | + |
44 | 90 | ## 平台支持与权限 |
45 | | -- Android:需要开启蓝牙并授予扫描/连接权限(Android 12+ 无需定位,11 及以下需定位权限)。 |
46 | | -- iOS / macOS:首次启动会请求蓝牙权限。 |
47 | | -- Linux / Windows:需设备具备 BLE 硬件和驱动支持。 |
48 | | -- Windows 额外提示:Flutter/CMake 在含中文或空格的路径下构建容易失败,建议将项目放在例如 `C:\\dev\\hr_osc` 的纯英文目录。运行时内置的 BLEServer 会自动解压到 ASCII 目录 `C:\\hr_osc_temp`,避免中文用户名导致的崩溃。 |
| 91 | +- Android:需要 BLE 扫描/连接权限(Android 12+ 无需定位,11 及以下需定位权限)。Android 13+ 若想显示常驻通知卡片,请允许通知权限。 |
| 92 | + - ColorOS/部分国产 ROM:需在系统设置中打开应用通知,并允许后台运行/自启动,否则可能看不到常驻卡片或后台停止更新。 |
| 93 | +- iOS/macOS:首次启动会请求蓝牙权限。 |
| 94 | +- Linux/Windows:需设备具备 BLE 硬件与驱动;内置 BLEServer 若检测到临时目录含非 ASCII 字符,会自动解压到 `C:\\Users\\Public\\hr_osc_temp` 以避免中文用户名/路径导致的启动失败。 |
49 | 95 | - Web:暂不支持(`flutter_blue_plus` 尚未覆盖 Web)。 |
50 | 96 |
|
51 | | -## 开发说明 |
52 | | -- 应用图标与产品 Logo 均由 `images/logo.png` 生成。 |
| 97 | +## 开发与构建 |
53 | 98 | - 主要代码:`lib/main.dart`(UI 与交互)、`lib/heart_rate_manager.dart`(扫描、连接、心率订阅与推送)。 |
54 | | -- 代码风格:2 空格缩进,`dart format .`;启用 `flutter_lints`(见 `analysis_options.yaml`)。 |
55 | | -- 测试:`flutter test`。当前提供默认测试脚手架,可按需补充 BLE/OSC 逻辑的 mocks/fakes。 |
56 | | - |
57 | | -## 进阶/规划 |
58 | | -- 数据留存与趋势图表(本地存储与导出)。 |
59 | | -- 阈值告警(系统通知 / 震动)。 |
60 | | -- 多设备偏好与后台保持策略。 |
61 | | -- 可配置的浅色主题与更多刷新策略。 |
| 99 | +- 代码风格:2 空格缩进;`dart format .`;启用 `flutter_lints`。 |
| 100 | +- 测试:`flutter test`。 |
| 101 | +- 打包:`flutter build apk|ios|windows|macos|linux`。 |
62 | 102 |
|
63 | 103 | ## 更新日志 |
64 | | -- **v1.2.2** |
65 | | - - Windows:内置 BLEServer 始终解压到 ASCII 目录 `C:\\hr_osc_temp`,彻底规避中文用户名/路径导致的启动失败。 |
66 | | - - Windows:最小化自动隐藏到系统托盘,悬停显示在线状态与心率摘要。 |
67 | | - - Android:发布构建启用 R8 混淆、资源压缩与 ABI 分包;Windows/macOS/iOS 开启链接优化以减小体积。 |
68 | | -- **v1.2.1** |
69 | | - - Windows:win_ble 临时目录改为 ASCII 路径(`C:\\hr_osc_temp`),解决构建产物放在中文目录或中文用户名下无法运行/崩溃的问题。 |
70 | | - - Windows:BLE 连接在数据长时间未更新时会主动重连,提升掉线恢复成功率。 |
71 | | -- **v1.2.0** |
72 | | - - Windows/macOS/Android/iOS 统一使用 `images/logo.png` 生成应用图标。 |
73 | | - - Windows:最小化/失焦时暂停心跳动画,降低 GPU 占用;检测心率数据长时间未更新时主动重连。 |
74 | | - - README 补充中文路径构建提示。 |
75 | | - - 依赖配置同步:`flutter_launcher_icons` 扩展桌面平台支持。 |
| 104 | +### v1.3.0 |
| 105 | +- 新增 MQTT 推送(Broker 填写即启用,端口/Topic/鉴权可配)。 |
| 106 | +- Android 新增通知栏常驻心率卡片,并自动按刷新间隔更新。 |
| 107 | +- RSSI 轮询刷新间隔与配置一致,连接后持续刷新信号。 |
| 108 | +- 自动重连逻辑与按钮状态修复,避免重连死锁和重复连接。 |
| 109 | +- Windows:BLEServer 在中文用户名/路径下运行更稳定(Public ASCII 临时目录 + 正确工作目录)。 |
| 110 | + |
| 111 | +### v1.2.2 |
| 112 | +- Windows:最小化自动隐藏到系统托盘,悬停显示在线状态与心率摘要。 |
| 113 | +- Android:发布构建启用 R8 混淆、资源压缩与 ABI 分包;Windows/macOS/iOS 开启链接优化以减小体积。 |
| 114 | + |
| 115 | +### v1.2.1 |
| 116 | +- Windows:BLE 连接在数据长时间未更新时会主动重连,提升掉线恢复成功率。 |
| 117 | + |
| 118 | +### v1.2.0 |
| 119 | +- Windows/macOS/Android/iOS 统一使用 `images/logo.png` 生成应用图标。 |
| 120 | +- Windows:最小化/失焦时暂停心跳动画,降低 GPU 占用;检测心率数据长时间未更新时主动重连。 |
| 121 | +- README 补充中文路径构建提示。 |
| 122 | +- 依赖配置同步:`flutter_launcher_icons` 扩展桌面平台支持。 |
76 | 123 |
|
77 | 124 | ## 贡献与反馈 |
78 | 125 | 欢迎提交 Issue / PR,一起完善 BLE 兼容性与推送链路。若在特定设备或平台遇到问题,请附上日志与环境信息,便于复现。 |
0 commit comments