【OBS連携】心拍数表示 (#185)
概要
OBS オーバーレイに心拍数(現在 BPM + 直近数分の推移グラフ)を表示します。beatoraja 本体が BLE 心拍計(CooSpo HW706 等、標準 GATT Heart Rate Service 0x180D / Measurement 0x2A37)にネイティブブリッジ経由で直接接続し、/state.json に乗せて overlay が表示します(クラウド非経由)。obsEnabled=false 時はゼロ影響。
構成
HW706 →(BLE notify)→ hrm-bridge (Rust+btleplug, natives/ に同梱)
→(stdout NDJSON {"bpm":N})→ HeartRateService → ObsState → /state.json
→(約1秒ポーリング)→ overlay (#heartrate 値+グラフ)
主な変更
-
tools/hrm-bridge: Rust + btleplug の BLE ブリッジ(0x180D スキャン→接続→0x2A37 購読→フラグバイト解析(UINT8/UINT16 LE)→
{"bpm":N}出力、バックオフ再接続、stdin EOF/SIGINT/SIGTERM で終了)。Windows バイナリnatives/hrm-bridge-win-x64.exeを同梱(既存natives/*.dllと同方式)。 - HeartRateService: ブリッジ子プロセスの起動/stdout 解析/1秒サンプリング/バックオフ再起動、バイナリ不在時は警告ログのみで no-op。
-
ObsState /
/state.json:heartRate{bpm, zone, zoneIndex, min, max, sampleSec, history[]}(null/stale 復帰、リングバッファ 3分、ゾーン算出)。snapshot の read-modify-write を単一ロックで直列化し、非同期心拍スレッドと changeState スレッドの lost-update を防止。 -
Config / 設定UI:
heartRateEnabled/heartRateMaxHr/heartRateDeviceFilter(PlayConfigurationView+ i18n 日英)。 -
overlay:
#heartrateに現在 BPM + MIN/MAX + inline SVG 折れ線グラフ(差分再描画、null/空で例外なし)。配色は他ブロックと同一テーマ色。README / state.sample.json 更新。
テスト
-
xvfb-run -a ./gradlew test→ BUILD SUCCESSFUL(Java 単体: heartRate JSON 形・ゾーン境界・リングバッファ上限/min/max・stale→null・bpm 行パース)。 - Rust: 0x2A37 フラグ解析の単体テスト(UINT8 / UINT16-LE / 短すぎるパケット)。
- overlay:
node --check+ DOM シム契約テスト(bpm/zone/polyline/null/単一点/空 history)。 - 実機(CooSpo HW706 + Windows)でブリッジ接続・overlay 表示を確認済み。
補足
- Windows バイナリは btleplug の WinRT 依存のため実機 Windows でビルドしコミット済み。Linux/Mac 版は未同梱(将来対応)。
-
heartRate.zone/zoneIndexは/state.jsonに残置(将来のテーマで色分けに利用可能、現 overlay の見た目には不使用)。