Umstellung auf 3.5
Diese Seite ist die zusammengefasste Upgrade-Anleitung für Inverse Service 3.5. Sie
behandelt alle veralteten Funktionen, die der Dienst noch enthält – die Legacy- 3.0
Das Wire-Format soll in 4.0, die veralteten HTTP-Endpunkte
und die veralteten Befehle zur Simulation von Sitzungskanälen – neben dem
einen neu In Version 3.5 eingeführte Neuerung: die optional aktivierbare „Wireless Verse Grip“-Ausgabeform.
Alle hier aufgeführten veralteten Funktionen werden aus Gründen der Abwärtskompatibilität weiterhin akzeptiert. Bei einem Upgrade treten keine Probleme auf – planen Sie die Migration nach Belieben.
3.0 vs 3.x API-Versionen
Der Dienst stellt zwei parallele JSON-Formate bereit: das alte 3.0 Format
am Port 10000 und der aktuelle 3.x Format am Port 10001. Beide bleiben
aus Gründen der Abwärtskompatibilität verfügbar — 3.0 Die Integrationen laufen
nach dem Upgrade unverändert weiter.
3.0 Die Unterstützung für API-Versionen wird eingestellt für 4.0.
-
3.0API- Vollständig dokumentiert in der
3.0.xDokumentationsseiten. HTTPauf http://localhost:10000/3.0/.Websocketsim Hafen10000.
- Vollständig dokumentiert in der
-
3.xAPI- Vollständig dokumentiert in der
3.xDokumentationsseiten. HTTPauf http://localhost:10001/.Websocketsim Hafen10001.- Verbesserte Funktionalität und schnellere Integration in Spiel-Engines.
- Vollständig dokumentiert in der
Führen Sie das Upgrade nach Belieben durch – ohne Unterbrechung Ihrer bestehenden Arbeitsabläufe.
Veraltete HTTP-Endpunkte
Die folgenden Endpunkte werden weiterhin akzeptiert, lösen jedoch eine Verwendungswarnung aus.
Sie werden in 4.0. Nutzen Sie stattdessen die Ausweichrouten.
| Veralteter Pfad | Ersatz |
|---|---|
POST /force_scale | POST /settings/devices/force_scale |
POST /gravity_compensation | POST /{type}/{id}/config/gravity_compensation |
POST /torque_scaling | POST /{type}/{id}/config/torque_scaling |
POST /device_handedness | POST /{type}/{id}/config/handedness |
POST /serial_enable | POST /settings/system/serial_enable |
POST /experimental/features/grip_dropped_simulation_stopper | POST /settings/features/grip_hook/enabled |
POST /experimental/features/screensaver_enable | POST /settings/features/screensaver/enabled |
Jede veraltete Route löst eine http-route-deprecated
Sendung auf dem Veranstaltungskanal, die sowohl die alte Strecke als auch deren
Ersatzstrecke zeigt.
Veraltete Befehle für Session-Channels
Die beiden folgenden Simulationsbefehle auf Sitzungsebene sind veraltet und werden
in einer zukünftigen Hauptversion entfernt. Sie werden weiterhin auf der
Übertragungsstrecke akzeptiert; neue Integrationen sollten den configure Einträge, die in der
Spalte „Ersatz“ aufgeführt sind.
Jeder veraltete Befehl löst einen command-deprecated
Veranstaltung auf dem Veranstaltungskanal.
session.set_coordinate_origin → inverse3[*].configure.preset
// Old — deprecated
{ "session": { "set_coordinate_origin": { "coordinate_origin": "workspace_center" } } }
// New — canonical
{ "inverse3": [ { "device_id": "…", "configure": { "preset": { "preset": "arm_front_centered" } } } ] }
Wertzuordnung:
Alt coordinate_origin | Neue Voreinstellung |
|---|---|
device_base | arm_front (oder defaults) |
workspace_center | arm_front_centered |
Voreinstellungen werden geräteweise über inverse3[*].configure.preset (oder
configure.preset (Einträge für den Verse-Grip / das drahtlose Verse-Grip-Gerät),
nicht als sitzungsweiter Schalter. Siehe die Abschnitt „Konfigurieren“
Die vollständige Liste der voreingestellten Namen finden Sie in der Simulationsanleitung.
session.set_basis → session.configure.basis
// Old — deprecated
{ "session": { "set_basis": { "basis": { "permutation": "X-ZY" } } } }
// New — canonical
{ "session": { "configure": { "basis": { "permutation": "XZ-Y" } } } }
Die Interpretation der Achsenbezeichnungen unterscheidet sich bei den beiden Befehlen. Eine
Permutation, die unter session.set_basis
kann ein invertierte Transformation unter
session.configure.basis — möglicherweise müssen Sie bei der Migration das Vorzeichen auf einer oder
mehreren Achsen umkehren.
Beispiel: Eine Sitzung, die korrekt ausgeführt wurde mit session.set_basis +
"permutation": "X-ZY" benötigt in der Regel "permutation": "XZ-Y" unter
session.configure.basis. Überprüfen Sie die resultierende Transformation stets erneut,
bevor Sie eine Migration ausliefern.
Ausgangsform des Wireless Verse Grip (3,5, optional)
Mit Serviceversion 3.5 wird ein optionales JSON-Format für Wireless-Verse-Grip-Geräte (einschließlich der kundenspezifischen Varianten Ruko und Kingfisher) sowohl im Voll-Snapshot- als auch im Streaming-Frame auf dem Simulationskanal v3.1 hinzugefügt.
3.5 wird mitgeliefert serialization/wireless_verse_grip/legacy_mode = true standardmäßig. Bestehende Clients aus der Zeit vor Version 3.5 funktionieren weiterhin ohne Konfigurations- und
ohne Codeänderungen – Sie können den Dienst aktualisieren, ohne Ihre
Integration anzupassen.
Führen Sie die Migration nur durch, wenn Sie wollen die neue Form: ein Reiniger
config.type / config.sub_type getrennte und explizite Steuerung darüber, ob
benutzerdefinierte Griffe über die gesamte wireless_verse_grip und
custom_verse_grip Arrays. Um sich anzumelden, setzen Sie
serialization/wireless_verse_grip/legacy_mode = false und befolgen Sie die weiteren
Anweisungen in diesem Abschnitt.
Die Änderung ist Zusatz auf dem Draht — Die Payload-Version v3.1 bleibt
unverändert — und wird vollständig durch vier Laufzeiteinstellungen unter
serialization/wireless_verse_grip/. Clients, die die Form vor Version 3.5 wünschen,
erhalten diese automatisch; Clients, die sich für die neue Form entscheiden, können drei
weitere Regler einstellen, um den Klang anzupassen.
Wer könnte daran interessiert sein, umzuziehen?
Jeder Client, der die wireless_verse_grip oder custom_verse_grip Arrays
einer v3.1-Nutzlast können von der neuen Form profitieren:
- Unity-Plugin-Integrationen, die WVG-Einträge über
JsonUtility - TouchDesigner -Integrationen, die den WebSocket-Stream nutzen
- Beispielcode für Python / C++
config.type(z. B."ruko"/"kingfisher")
Kunden, die nur analysieren inverse3 oder verse_grip Arrays sind nicht
betroffen unabhängig von den Einstellungen.
Anmeldung
Umdrehen legacy_mode zu false um die neue Form zu aktivieren. Es gibt zwei Möglichkeiten:
- HTTP (Laufzeit)
- Konfigurationsdatei (persistent)
curl -X POST http://127.0.0.1:10001/settings/serialization/wireless_verse_grip/legacy_mode \
-H 'Content-Type: application/json' \
-d 'false'
Der Dienst sendet sofort einen vollständigen Snapshot erneut, sodass Clients, die sich mitten in der Übertragung befinden, die neue Form im nächsten Frame sehen.
Füge den Schlüssel hinzu haply-inverse-service-config.json:
{
"serialization/wireless_verse_grip/legacy_mode": false
}
Speicherorte der Konfigurationsdateien (einer davon):
| Plattform | Pfad |
|---|---|
| Windows | C:\ProgramData\Haply\Inverse\haply-inverse-service-config.json |
| macOS | /Library/Application Support/Haply/Inverse/haply-inverse-service-config.json |
| Linux | /etc/haply-inverse-service/haply-inverse-service-config.json |
Starten Sie den Dienst (oder den Haply ) neu, damit die Änderung wirksam wird.
Sobald legacy_mode = false, die anderen Regler (explicit_custom,
extended_data/raw_data, extended_data/custom_fields) werden aktiv. Siehe
die Knopfmatrix unten.
Wie die neue Form aussieht
Wenn Sie sich dafür entscheiden (legacy_mode = false), legt die Nutzlast Achsen fest, die
zuvor miteinander verflochten waren:
config.typeist die Stammfamilie, pro Eintrag —"wireless_verse_grip"für Stiftreihen,"custom_verse_grip"für benutzerdefinierte Zeilen (Ruko, Kingfisher, Prototyp).config.sub_typeist ein neues Gebiet (nur Opt-in-Form) mit dem Subtyp „physische Hardware“ —"stylus","prototype","ruko", oder"kingfisher". Es serialisiert diewireless_verse_grip::subtypeenum direkt, im Unterschied zuconfig.type'sdevice_typeenum. Bisher wurden sowohl „stylus“ als auch „prototype“ serialisiert als"wireless_verse_grip"; jede hat nun ihren eigenen Wert. Der Legacy-Modus nicht ausstoßensub_type.- Individuelle Griffe teilen
wireless_verse_grip[]standardmäßig Wenn Sie sich dafür entscheiden, enthält das Stylus-Array auch die benutzerdefinierten Varianten. Die separatecustom_verse_gripDas Array wird nur ausgegeben, wenn du umdrehstexplicit_custom = trueIn diesem Fall ist dieses Array nur benutzerdefiniert (der Stylus erscheint dort nie). - Benutzerdefinierte Payloads bleiben als rohe Erweiterungsbytes erhalten.
extended_data/raw_data(Standardtrue) behält die Rohdaten beistate.extension_data: [...]Byte-Array bei benutzerdefinierten Griff-Einträgen — das der bisherigen Form entspricht. Es wird erwartet, dass Clients diese Bytes in ihrem eigenen Code in untertyp-spezifische Felder (Ruko-Rad/Auslöser, Kingfisher-Tasten , …) umwandeln; ein spezielles Flag für fortgeschrittene Funktionenextended_data/custom_fieldskann vorübersetzte Felder innerhalb des Dienstes ausgeben, aber es ist nicht Teil des empfohlenen Migrationspfads – lies dir den Hinweis zu diesem Regler durch, bevor du ihn aktivierst.
Beispiel: „Legacy“ (Standard) vs. „Opt-in“
Nehmen wir an, es gibt einen Stift (1615) und ein Ruko (1419) miteinander verbunden sind.
- Legacy (Standard: 3.5)
- Opt-in (legacy_mode = false, Standardwerte)
{
"wireless_verse_grip": [
{
"device_id": "1615",
"config": { "type": "wireless_verse_grip", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
}
},
{
"device_id": "1419",
"config": { "type": "ruko", "…": "…" },
"state": {
"buttons": { "up": false, "down": false, "left": false, "right": false },
"trigger": 7,
"wheel": 4,
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
}
}
],
"custom_verse_grip": [
{
"device_id": "1419",
"config": { "type": "custom_verse_grip", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 },
"extension_data": [0, 6, 1, 183, 5, 6, 7, 8, 9, 10, 11, 12]
}
}
]
}
{
"wireless_verse_grip": [
{
"device_id": "1615",
"config": { "type": "wireless_verse_grip", "sub_type": "stylus", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 }
}
},
{
"device_id": "1419",
"config": { "type": "custom_verse_grip", "sub_type": "ruko", "…": "…" },
"state": {
"buttons": { "a": false, "b": false, "c": false },
"hall": 16,
"orientation": { "x": 0, "y": 0, "z": 0, "w": 1 },
"extension_data": [0, 6, 1, 183, 5, 6, 7, 8, 9, 10, 11, 12]
}
}
]
}
In diesem Beispiel befinden sich alle drei anderen Regler in ihrer Standardposition
(explicit_custom = false, raw_data = true, custom_fields = false),
daher teilen sich die Zollbehörden die wireless_verse_grip Array, das separate
custom_verse_grip Das Array wird nicht ausgegeben, und der Ruko-Eintrag enthält die
Rohdaten extension_data Byte-Array, das der Client lokal übersetzen soll.
Die wichtigsten Unterschiede bei einer Anmeldung:
| Aspekt | Legacy (Standard: 3.5) | Anmeldung (legacy_mode = false) |
|---|---|---|
config.type für benutzerdefinierte Zeilen unter wireless_verse_grip | Name des Subtyps (z. B. "ruko") | Elternfamilie "custom_verse_grip" |
config.sub_type | abwesend | gegenwärtig — "stylus" / "prototype" / "ruko" / "kingfisher" |
custom_verse_grip Array ausgegeben | immer (wenn ein benutzerdefinierter Griff angeschlossen ist) | nur wenn explicit_custom = true |
| Schema für benutzerdefinierte Zustände | roh extension_data Bytes + a/b/c Tasten | derselbe Rohstoff extension_data standardmäßig Bytes; raw_data kann deaktiviert werden, und custom_fields ist eine erweiterte Opt-in-Funktion – siehe unten |
Stift unter custom_verse_grip | niemals | niemals |
Anpassung Ihres Parsers
Sobald Sie sich angemeldet haben, behandeln Sie config.sub_type als die Hardware-Identität und
config.type als die Familien-Bucket. Kunden, die sich zuvor angemeldet hatten
config.type == "ruko" sollte sich daran orientieren config.sub_type == "ruko":
- const isRuko = entry.config.type === "ruko";
+ const isRuko = entry.config.sub_type === "ruko";
Für Parser, die sowohl Serviceversionen vor 3.5 (oder 3.5-Services, die sich noch im Legacy-Modus befinden) als auch 3.5-Services im Opt-in-Modus in derselben Binärdatei unterstützen müssen, aktivieren Sie eines der beiden Felder:
const subtype = entry.config.sub_type ?? entry.config.type;
const isRuko = subtype === "ruko";
Jeder Kunde, der sich bisher auf übersetzt Felder pro Untertyp
innerhalb eines Ruko- oder Kingfisher-Eintrags (buttons.{up,down,left,right},
trigger, wheel, buttons.{a..f}, …) sollte nun die Rohdaten übersetzen
state.extension_data[] Bytes auf seiner Seite. Der Dienst behält die
alte, noch in Betrieb befindliche Übersetzung hinter der
extended_data/custom_fields Flag,
dieses Flag ist jedoch ausschließlich für ganz bestimmte interne Clients vorgesehen, und
die derzeitige Übersetzung soll in einer zukünftigen Version vollständig aus dem Dienst entfernt werden –
integrieren Sie den Byte-Decoder von Anfang an auf der Client-Seite,
um eine spätere Migration zu vermeiden.
Weiterhin Nutzung des alten Systems (keine Maßnahmen erforderlich)
In Version 3.5 ist standardmäßig der Legacy-Modus aktiviert. Wenn Sie einen Client haben, der nicht aktualisiert werden kann, oder wenn Sie die neue Form noch nicht benötigen, brauchen Sie nichts zu unternehmen – ein Upgrade auf 3.5 hat keine Auswirkungen auf Ihre Daten.
legacy_mode = true ist in Version 3.5 die Standardeinstellung, um Haply internen Haply
(einschließlich des Hubs) und den First-Party-Integrationen Zeit für die Migration zu geben. Es ist
nicht veraltet heute, aber die Standardeinstellung soll wieder auf
false in einer zukünftigen Nebenversion, und die Einstellung selbst wird voraussichtlich
vor dem großen Versionssprung auf 4.0 entfernt. Planen Sie die Umstellung, sobald es Ihnen passt – warten Sie nicht
auf eine feste Frist.
Vollständige Knopfmatrix
Alle vier Regler befinden sich unter serialization/wireless_verse_grip/ und kann
zur Laufzeit über die HTTP-API für Einstellungen umgeschaltet werden.
Knopf: legacy_mode
- Typ:
bool - Standard:
true(3.5 wird mit aktiviertem Legacy-Modus ausgeliefert)
Wenn true, entspricht die Nutzlast Byte für Byte der Form vor Version 3.5, und die
anderen Regler haben keine Wirkung mehr. Wenn false, ist die neue Form aktiv und die
drei Regler darunter werden wirksam. Siehe Anmeldung.
Knopf: explicit_custom
- Typ:
bool - Standard:
false - Erfordert
legacy_mode = falseum irgendeine Wirkung zu erzielen.
Legt fest, ob benutzerdefinierte Griffe ein eigenes Array erhalten.
false(Standard) — Zollanteilwireless_verse_grip[]Array neben den Eingaben mit dem Stift; keine separatecustom_verse_gripDas Array wird ausgegeben.true— Zölle werden ebenfalls im Rahmen eines speziellencustom_verse_grip[]Array (und erscheinen weiterhin unterwireless_verse_grip[](auch).
Das vorherige merged_in_wireless Einstellung umgekehrt: Standardmäßig war
true (Zollangaben wurden in wireless_verse_grip) und musste auf
false um eine klare Trennung zu erreichen. Die neue Benennung ist positiv — explicit_custom = true lautet „Zölle explizit unter ihrem eigenen Array ausgeben“ – und die
Standardeinstellung wurde umgekehrt, sodass der standardmäßige Opt-in-Modus ein einziges
einheitliches wireless_verse_grip[] Array, wodurch der Aufwand für die Serialisierung pro Takt reduziert wird.
Knopf: extended_data/raw_data
- Typ:
bool - Standard:
true - Erfordert
legacy_mode = falseum irgendeine Wirkung zu erzielen.
Wenn true (Standard), benutzerdefinierte Grip-Einträge enthalten die Rohdaten
state.extension_data: [...] Byte-Array – die stabile Struktur für
reflexionsbasierte Deserializer wie die von Unity JsonUtility und für Clients,
die ein benutzerdefiniertes Binärprotokoll über den Erweiterungskanal nutzen. Wenn false,
wird das Byte-Array weggelassen. Unabhängig von custom_fields; die vier Kombinationen entnehmen Sie bitte der
nachstehenden Tabelle.
Keine Aktion beim Subtyp „einfacher Stylus“ (kein Erweiterungskanal).
Knopf: extended_data/custom_fields
- Typ:
bool - Standard:
false - Erfordert
legacy_mode = falseum irgendeine Wirkung zu erzielen.
custom_fields wird für eine Handvoll bestimmter interner Clients beibehalten, die
nach wie vor auf den Dienst angewiesen sind, um Rohdaten der Erweiterung in
subtyp-spezifische Felder zu übersetzen. Es ist geplant, die Übersetzung während des Betriebs zu verlagern aus
dem Dienst in einer zukünftigen Version, daher sollten neue Integrationen nicht
Aktivieren Sie dieses Flag. Behalten Sie custom_fields = false (Standard) und führen die
Umwandlung von Bytes in Felder auf der Client-Seite durch.
Wenn true… erhalten Einträge mit benutzerdefinierten Griffen das übersetzte Schema pro Untertyp —
buttons.{up,down,left,right} + trigger + wheel für Ruko;
buttons.{a..f} + trigger für Kingfisher. Wenn false (Standard),
nur die allgemeine buttons.{a,b,c} sind vorhanden und der subtypspezifische Zustand
muss daraus entschlüsselt werden state.extension_data[]. Unabhängig von
raw_data.
Keine Aktion beim Subtyp „plain stylus“ und beim Subtyp „prototype“ – der
Prototyp verfügt über kein übersetztes Schema und greift immer auf
extension_data Bytes (falls raw_data = true) oder in die Standardansicht a/b/c Schaltflächen
nur (wenn raw_data = false).
Kombinierte Matrix (Opt-in-Modus)
Mit legacy_mode = false:
explicit_custom | raw_data | custom_fields | wireless_verse_grip[] enthält | custom_verse_grip[] enthält |
|---|---|---|---|---|
false (Standard) | true (Standard) | false (Standard) | Stift (einfach) + benutzerdefiniert (Rohdaten) | (wird nicht ausgegeben) |
false | false | true | Stift (unbeschriftet) + Zoll (übersetzt) | (wird nicht ausgegeben) |
false | true | true | Stift (unformatiert) + benutzerdefiniert (Rohdaten + übersetzt) | (wird nicht ausgegeben) |
true | true | false | Stift (einfach) + benutzerdefiniert (Rohdaten) | Zoll (Rohdaten) |
true | false | true | Stift (unbeschriftet) + Zoll (übersetzt) | Zoll (übersetzt) |
true | true | true | Stift (unbearbeitet) + Zoll (unbearbeitet + übersetzt) | Zoll (Original + Übersetzung) |
(Zeilen mit raw_data = false und custom_fields = false sind zulässig, geben jedoch
nur den generischen a/b/c Schaltflächen – in der Regel nicht sinnvoll.)
Prototyp-Untertyp
Der Prototyp des Untertyps „Custom-Grip“ wird für Routing-Zwecke als benutzerdefiniert behandelt
– er erscheint unter wireless_verse_grip[]sowie unter
custom_verse_grip[] wenn explicit_custom = true. Da es kein
übersetztes Schema für den Prototyp gibt, custom_fields hat bei Prototyp-Einträgen keine Auswirkung;
ihr Zustand stammt vollständig aus extension_data Bytes (wenn
raw_data = true) oder gar nicht (wenn raw_data = false).
Im Opt-in-Modus melden Prototyp-Einträge config.sub_type = "prototype" —
ein eigener Enum-Wert, der sich von "stylus". In 3.4 werden beide Untertypen
als "wireless_verse_grip"; 3.5 Im Opt-in-Modus erhält jedes Element einen eigenen
Wert. Im Legacy-Modus wird nichts ausgegeben sub_type überhaupt nicht.
Referenz
- Übersicht über die Einstellungen — die vier
serialization/wireless_verse_grip/*Tasten. - WebSocket-Protokoll – vollständiger Überblick und Aufbau der Streaming-Frames.
- AsyncAPI-Referenz – maschinenlesbares Schema für alle v3.1-Nutzdaten.
- HTTP-API-Referenz – Swagger UI für die aktuellen HTTP-Routen und deren Ersatz für die oben aufgeführten, veralteten Endpunkte.