Lighthouse 2.0 の BaseStation (Valve) の電源状態をLinuxマシンから操作する

Androidアプリで操作できるってきいたんでLinux PCから操作できないわけはないだろうということでためしてみる

まずはベースステーションについて

一言にSteamVRデバイス、といっても様々なデバイスが存在しますが、そのなかでもValve IndexやVive Proなどは標準でValveのLighthouse2.0を使用しています。これらのフルセットを買うとついてくるのが所謂ベースステーション2.0。

SteamVRはその仕組み上、これがなければはじまりません。

BaseStation 2.0

さて、このベースステーションですが、内部ではモーターが高速で回転しており起動中は高周波の音を発生させています。VRのプレイ中はたいして気にはなりませんが、普段はその騒音がかなりきになるところ。また、これによって衝撃による故障も発生しやすくなっています。困った子で、私も初回購入時には1週間たたずに死の赤点滅にみまわれRMAに……。

そんなベースステーションですが、(当然使用者の方であればご存知でしょうが) SteamVR から電源管理を行うことができます。ベースステーションには通常起動の状態以外にスリープとスタンバイの電源状態が用意されているのです。

SteamVRのベースステーションの電源管理設定画面
ベースステーションの電源管理

ベースステーションの電源管理にはBluetooth (あとで重要ですがBLE)を使用します。

しかし、私の知る限りSteamVRからSteamVRの開始/終了にあわせてこの電源管理を使用するにはHMDやリンクボックスに内蔵されているBTコントローラーのみが使用できるようです。ちなみにこのBTコントローラーは(少くともIndexでは)いずれかのVRコントローラーと無線アンテナを(?)共有しており、排他使用になっているようです。

しかし、HMDをHMDと使用していない状態ではたとえHMDのUSBのみが接続されていようが、PCにBluetoothのドングルが接続されていようが、SteamVRでBluetoothを利用することはできないようです。

Bluetooth設定「ブルートゥースが利用できません」
HMDが有効でないときはBluetoothが利用できない

普通の使い方をしていればこれで問題ないのかもしれませんが、一部の特殊な使い方をしていると地味に不便な話です。そう、たとえばHMDにはOculus Questを使いつつコントローラーやトラッカーにLighthouseを使用する我々には。

そもそも稀に電源管理が正しく機能しないこともあるのでスマートコンセントを使用してそもそものコンセントの制御をGoogleアシスタントで完結するようにしているのですが、ちゃんと仕組みを知って自分で操作したいと思うのが開発者心。

参考になりそうなAndroidアプリの存在

ベースステーションをSteamVR以外から操作できる先行事例として、Lighthouse Power ManagementというAndroidアプリが公開されているようです。うれしいことに、このアプリはGPL3+のオープンソースソフトウェアであり、GitHubで公開されています。なおflutter製。

Androidアプリとはいったものの、どうやらiOSやLinux、ましてやWeb bluetoothでも動作したり、なんならWindowsサポートも準備中のようです。もうこれでいいのでは

このアプリはSteamVR2.0だけでなくてLighthouse1.0、初代Viveのほうもサポートしています。万能。操作したいだけならこれつかえばいいや!

や、BLEを完全に理解したいんだ!(無茶)

あと、How to Power Off Basestations remotely [SOLVED] – Pimax Hardware / Pimax Discussion – OpenMR | Communityっていうスレッドも参考になりそう。

先人の調査に感謝。

LinuxのCLIからBSを操作する

やっとこさ本題。

とりあえず前述のアプリのソースコードをながめると、BaseStationとの通信をBLE (Bluetooth Low Energy)でおこなっていることがよくわかります。なかでもLighthouse2.0のBSの定義をしているのがこのクラス。あとで色々と参考にしましょうね。

おもにこれを参考に、コマンドラインでベースステーションを操作していきます。

環境

さて、今回の実験を行う環境の前提条件は以下のとおり。いつもの環境。

  • ThinkPad X395 (Ryzen 5 PRO 3500U)
  • ArchLinux (5.13.12-AMD x86_64 GNU/Linux)
  • BT: Intel Wireless-AC 9260

内蔵のWLANカードを利用していますが、今時のBTドングル等もBLEは対応してそうなのでとりあえずBLEの使えるものがあればOK。

今回はBlueZのBLE機能をレガシーAPIから使用するため、 bluez-utils ではなく、aurから bluez-utils-compatをインストールしておきます。最終的にはいらなかったんだけどbtgatt-clientわかりにくい部分もあったので。

既にbluez-utilsがインストールされている環境ではリプレースすることになりますね。

今回用いるレガシーなAPIについてはこちらのエントリがいいかんじに参考になりました。

BLEデバイスのスキャン

まずはBSをみつけるため、BTデバイスをスキャンします。

hcitoolではうまくうごかない場合もありました。普通にbluetoothctlで大丈夫。

BLEを使用するのにペアリングの必要はありません。Coke On PayやLINEのBLEビーコンだってそうでしょ?とりあえずMACアドレスをひかえておきましょう。

接続してサービスをみつける

MACアドレスがわかったところで早速接続してみます。BLEのGATT通信ってやつを使うことでBLEデバイスとデータがやりとりできるようです。レガシーAPIですが今回はまずgatttoolを使用します。ざっくりコマンドの確認もしておきましょう。

あ、まだこの時点では接続してないんです。接続してプライマリサービスの一覧をみてみましょう。接続できるとMACアドレスの部分が青くなるようです。

…UUIDだけみても正直それがなにをさしている値なのかはよくわかりません。ここで参考資料の出番です。どうやら3つめの00001523-1212-efde-1523-785feabcd124がコントロールを司っているサービスのようです。(ほかはなにしてるんでしょう、FWのアップデートとかも関係あるはず……)

では、当該のサービスの中身をみてみます。

たしかに参考コードでみたUUIDがでてきました。上から順に識別用(0x10)、電源管理(0x12)、チャンネル管理(0x15)のようです。

もっとも、今回はUUIDがわかっているのでこんなことをせずともUUIDからツールにまかせてハンドルや値が取得できます。

電源状態は0bのようです。0bってどういう状態でしょうか。

どうやら、通常の起動時がこれのようですね。たしかに今当該のベースステーションは緑色LEDが点灯しています。

ベースステーションをスリープにする

ここまで来れば電源管理を行うのは簡単です。確認したハンドルに値を書き込むだけ。ちなみに電源管理は

  • 00: スリープ
  • 01: 起動
  • 02: スタンバイ

となっているようなので必要な値をかきこみます。

はい。これだけ。ベースステーションがスリープに落ちました!

なお、char-write-reqは相手先機器から返事をまちますが、char-write-cmdで投げっぱなしにすることも可。

1コマンドで操作する

ここまでgatttoolsの対話型インタフェース内でコマンドを打ってきましたが、ハンドルと値がわかったのでコマンドを直接引数から指定して実行できます。

はい。たったこれだけ。ベースステーションが起動しました。ただ時々失敗することもあるみたい。なんで……

モダンなAPIを使う

くりかえしますがgatttoolは廃止されたレガシーなAPIです。bluetoothctlはroot権限なしでつかえるのにgattoolはrootいるんだもん、あれだよね。っていうことでそう、今のBlueZではGATTはbtgatt-clientでD-Bus経由で扱えるようです。sudo不要です。

では試してみましょう。

お前勝手に全サービス表示してくれるんかい!

……ではスリープにしてみます。やることは一緒。

簡単!!!!!!おしまい!!!!

ついでなんでベースステーションの識別もしてみましょう。LEDが白色点滅するやつです。これには0x00に適当なバイトを書き込むだけです。値はなんでも大丈夫な模様。

ベースステーションのLEDが点滅しました。識別したいときに使いましょう。


まとめ

ということでBlueZからGATTでベースステーションとおしゃべりをしました。BLEの内部実装はさておき、表にでてるインタフェースは結構単純になってるようで助かります。

本当はD-Busを叩いて操作するやつもしたかったものの一気に面倒になったりほしい部分がまだなかったりするようなこともあったのでパス。アドバタイズとかについてはほとんど触れなかったものの、ここまでわかれば色々な実装ができそうな気がして……こない?WindowsもAPIとかあるみたいだし。


コメントを残す