00. 機器一覧
HTTP REST API を通じて、接続済みのすべてのHaply デバイスを検出します。WebSocket は不要です。これは、ランタイムが起動しており、ハードウェアを検出できることを確認するための簡単なスモークテストです。
学習内容:
- 検索
GET /devicesInverse3、VerseGrip、およびワイヤレスVerseGripデバイスを一覧表示します - JSON レスポンスからデバイス ID を読み取り、デバイスタイプごとにグループ分けする
- セッションセレクターを使用して、原点座標系とセッションのアプリケーション空間ビューを切り替える
ワークフロー
- 送信
GET http://localhost:10001/devices。 - JSONレスポンスの解析――3つの最上位の配列が含まれています:
inverse3、verse_grip、wireless_verse_grip。 - デバイスIDをタイプ別に表示します。配列が空の場合、そのタイプのデバイスは検出されなかったことを意味します。
- もし~ならば
?session=<selector>形式の追加会話セレクター,応答ではそのセッションのデバイスのみがフィルタリングされ、座標はそのアプリケーション空間(basis、mount、workspace 変換が適用済み)に変換されます。Python のサンプルは--session SELECTORこの機能はコマンドライン引数の形式で提供されます(以下の形式が使用可能です:profile:instance、#id、:-1、:0、…)——とチュートリアル 08(HTTP によるリモート設定)使用されるパラメータは同じで、ヘルプテキストも一致しているため、ここで見つけたセレクタをそのままそこに貼り付けることができます。C++ のサンプルでは、クエリ実行時にセレクタは使用されません。
パラメータ
| パラメータ | デフォルト値 | 用途 |
|---|---|---|
| サービスURL | http://localhost:10001 | HTTP の基本:URL |
| 端点 | /devices | エンドポイントの検出 |
| 会話セレクター | (なし) | ?session=:0、?session=:-1、?session=:my_profile:0、?session=co.haply.hub::*:0(glob ワイルドカードに対応)——参照セレクタ。Python の例では、 --session SELECTOR の形式で提供(とチュートリアル 08(同じ引数)。 |
重要なコード
- Python
- C++ (nlohmann)
- C++ (Glaze)
Python の例では、セッションセレクタを --session SELECTOR argparse パラメータで指定します。このパラメータを指定しない場合、デバイスは原点座標系で返されます。指定すると、デバイスは選択されたセッションにフィルタリングされ、アプリケーション座標系に変換されます。ヘルプテキストとチュートリアル 08(HTTP によるリモート設定)一致するため、ここで見つかったセレクタをそのままそこに貼り付けることができます。
def parse_args():
parser = argparse.ArgumentParser(
description="List connected Haply Inverse devices via the HTTP API.")
parser.add_argument(
"--session", type=str, default="",
help=(
"Session selector. Formats:\n"
" :profile:instance by profile name (e.g. ':my_profile:0')\n"
" pattern:instance glob wildcard in profile (e.g. 'co.haply.hub::*:0')\n"
" '*' matches any sequence, '?' one character\n"
" #session_id by numeric id (e.g. '#42' — quote in shells to escape '#')\n"
" :-1 the last active session\n"
" :0 the first session"
))
return parser.parse_args()
def main():
args = parse_args()
session = args.session or None
url = f"{BASE_URL}/devices"
if session:
url += f"?session={session}"
print(f"Querying devices for session '{session}' (application space)\n")
else:
print("Querying all detected devices (device space)\n")
r = requests.get(url, timeout=3)
r.raise_for_status()
data = r.json()
print_devices("Inverse3", data.get("inverse3"))
print_devices("Wired Verse Grip", data.get("verse_grip"))
print_devices("Wireless Verse Grip", data.get("wireless_verse_grip"))
C++ バリアントの使用 libhv HTTP を処理し、nlohmann/json を使用して解析を行います。これは、 contains() 各トップレベルキーを手動で確認し、配列が空でない場合はその配列を順に処理します。C++ のサンプルでは、セッションセレクタのコマンドライン引数は提供されていません。空間座標を適用するには、URL の末尾に以下を追加してください。 ?session=<selector>。
HttpResponsePtr resp = requests::get("localhost:10001/devices");
if (resp == nullptr) { /* ... error ... */ return 1; }
json data = json::parse(resp->body);
if (data.contains("inverse3") && !data["inverse3"].empty()) {
printf("Inverse3 found:\n");
for (auto &element : data["inverse3"]) {
printf(" (id: %s)\n", element["device_id"].get<std::string>().c_str());
}
}
// ... same pattern for verse_grip and wireless_verse_grip
Glaze のバリアントは、JSON 構造と一致する一般的な構造体を宣言しており、Glaze はコンパイル時のリフレクションを通じてこれらの構造体を自動的に埋めます。以下の操作を行う必要はありません。 contains() チェック:欠落している配列は空の std::vector<> 戻る。
static constexpr glz::opts glz_settings{.error_on_unknown_keys = false};
struct device_entry { std::string device_id; };
struct devices_response {
std::vector<device_entry> inverse3;
std::vector<device_entry> verse_grip;
std::vector<device_entry> wireless_verse_grip;
};
// In main():
HttpResponsePtr resp = requests::get("localhost:10001/devices");
devices_response data;
if (auto err = glz::read<glz_settings>(data, resp->body)) {
printf("JSON parse error: %s\n", glz::format_error(err, resp->body).c_str());
return 1;
}
for (const auto &dev : data.inverse3) {
printf(" (id: %s)\n", dev.device_id.c_str());
}
チュートリアル 00 も SDK とともにローカルにインストールされます。サービスのインストールディレクトリ内をご確認ください。 tutorials/00-haply-inverse-device-list/。