00. Geräteliste
Erkennt alle verbundenen Haply-Geräte über die HTTP-REST-API — ohne WebSocket zu benötigen. Ein einfacher Smoke-Test, der prüft, ob die Laufzeitumgebung aktiv ist und Hardware erkennt.
Was Sie lernen:
- Abfragen von
GET /devices, um Inverse3-, VerseGrip- und drahtlose VerseGrip-Geräte aufzulisten - Auslesen der Geräte-IDs aus der JSON-Antwort, gruppiert nach Gerätetyp
- Verwendung eines Sitzungsselektors, um zwischen den rohen Gerätekoordinaten und der Anwendungsraum-Ansicht einer Sitzung zu wechseln
Ablauf
- Senden Sie
GET http://localhost:10001/devices. - Parsen Sie die JSON-Antwort — drei Arrays auf oberster Ebene:
inverse3,verse_grip,wireless_verse_grip. - Geben Sie die Geräte-IDs nach Typ gruppiert aus. Leere Arrays bedeuten, dass kein Gerät dieses Typs erkannt wurde.
- Wenn ein Sitzungsselektor als
?session=<selector>angehängt wird, wird die Antwort auf die Geräte dieser Sitzung gefiltert und die Koordinaten werden in deren Anwendungsraum umgerechnet (Basis, Montage und Workspace angewendet). Das Python-Beispiel stellt dies als CLI-Argument--session SELECTORbereit (akzeptiert:profile:instance,#id,:-1,:0, …) — mit demselben Flag und demselben Hilfetext, den auch Tutorial 08 (HTTP Remote-Konfiguration) verwendet, sodass ein hier gefundener Selektor direkt dort eingefügt werden kann. Die C++-Beispiele fragen ohne Selektor ab.
Parameter
| Parameter | Standard | Zweck |
|---|---|---|
| Dienst-URL | http://localhost:10001 | Basis-URL von HTTP |
| Endpunkt | /devices | Endpunkt für die Geräteerkennung |
| Sitzungsselektor | (keiner) | ?session=:0, ?session=:-1, ?session=:my_profile:0, ?session=co.haply.hub::*:0 (Glob-Platzhalter werden unterstützt) — siehe Selektoren. Im Python-Beispiel als --session SELECTOR verfügbar (gleiches Flag wie Tutorial 08). |
Wichtiger Code
- Python
- C++ (nlohmann)
- C++ (Glaze)
Das Python-Beispiel stellt den Sitzungsselektor als argparse-Argument --session SELECTOR bereit. Ohne dieses Argument werden die Geräte in den rohen Gerätekoordinaten zurückgegeben; mit dem Argument werden sie auf die ausgewählte Sitzung gefiltert und in den Anwendungsraum umgerechnet. Der Hilfetext entspricht dem von Tutorial 08 (HTTP Remote-Konfiguration), sodass ein hier gefundener Selektor direkt dort eingefügt werden kann.
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"))
Die C++-Variante verwendet libhv für HTTP und nlohmann/json zum Parsen. Sie prüft jeden Schlüssel der obersten Ebene manuell mit contains() und iteriert über das Array, sofern es nicht leer ist. Die C++-Beispiele bieten das CLI-Argument für den Sitzungsselektor nicht an — hängen Sie ?session=<selector> an die URL an, wenn Sie Koordinaten im Anwendungsraum benötigen.
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
Die Glaze-Variante deklariert einfache Structs, die die Form von JSON widerspiegeln — Glaze füllt sie zur Kompilierzeit über Reflexion. Es sind keine contains()-Prüfungen nötig: fehlende Arrays werden als leere std::vector<> zurückgegeben.
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());
}
Tutorial 00 ist außerdem lokal mit dem SDK installiert — sehen Sie im Installationsverzeichnis des Dienstes unter tutorials/00-haply-inverse-device-list/ nach.
Quelle: Python · C++ · C++ Glaze
Verwandt: JSON Konventionen · Selektoren · Sitzungen