Skip to main content
Version: 3.5.x

v3.5.1

3.5.1 is a stabilization and quality release. Headline themes: auto-pairing for 1↔1 Inverse3 + grip setups, fresh GET /devices/{id} motion state without an open WebSocket session, an end to the force/position mode-flip screech, and a self-tuning service tick scheduler under sustained load.

Highlights

  • Auto-pairing for 1↔1 Inverse3 + grip installs. When one Inverse3 and one grip are ready, the SDK registers a pairing automatically — pen_attached and Minverse calibration unlock stop misrouting in multi-device setups.
  • Fresh GET /devices/{id} snapshots without an open session. Inverse3 / Inverse3x / Minverse on firmware v7.5+ now have motion state polled at 20 Hz regardless of WebSocket activity. Pre-v7.5 firmware skips the poll and warns once.
  • Force/Position swap no longer screeches. Switching set_cursor_forceset_cursor_position is slot-exclusive — only the latest per device survives between ticks. HARP's 200 ms idle-gap workaround is obsolete.
  • Self-tuning tick scheduler. The main loop adapts its dispatch rate under load so a slow tick can't grow the command queue without bound.
  • 1-in-1-out streaming replies under load. Per-WS-message streaming replies are capped at 1/ms per session; the previous buffer is replayed when the cap denies, so sim loops never block on recv().

Internal improvements

Devices

  • Per-device Inverse3 ↔ VerseGrip pairing registry. GET|POST|DELETE /devices/{sel}/paired_with is a per-device 1:1 map. POST evicts conflicts on either side; DELETE clears the selected entry; selector must resolve to one ID.
  • 20 Hz motion-state poll on firmware v7.5+. GET /devices/{id} returns fresh cursor_position, cursor_velocity, angular_position, angular_velocity every 50 ms; transparent to active sessions.
  • Wireless VerseGrip set_extension_data rate-controlled. Drop-older / repeat-on-idle pipeline drained on the service tick — over-sending no longer saturates the radio link, under-sending no longer leaves a stale value.

Sessions

  • New WS-receive fast-path for control-only batches (force/position) skips the configure-aware pipeline; configure / set_profile / custom commands still go through the race-fix.

Observability

  • Detection log cadence is per-port and chronicity-aware. Each blacklisted port is gated independently; the recurring "...blacklisted: skipping" line now carries (×N) for ticks silenced between fires.
  • Wireless VerseGrip detection no longer floods the log when a non-WVG device is probed.

Fixes

  • POST /device.config.preset with defaults or arm_front now resets the device's mount to the factory preset (was a silent no-op). basis is preserved so app-configured bases survive mount preset changes.
  • force_render_full_state no longer returns a snapshot with a missing config block when the matching configure landed in the same WS message — the configure path drains synchronously before the snapshot.
  • Cross-session force_render_full_state returns the target's full snapshot. Both A and B now see a full payload (was: A received streaming-only).
  • Cross-session commands with an unknown target_session_id no longer hang the request-reply loop. Requester receives its own snapshot + a session-command-dropped event (cross-session-unknown-target).
  • Minverse multi-device calibration unlocks no longer misroute. Calibrating Minverse A no longer unlocks Minverse B; same fix for the inkwell-success heading broadcast.
  • HTTP device selector accepts #1234 and 1234 as device ID; selector classes (inverse3, verse_grip) work alongside index; 404 messages preserve the original selector expression.
  • Wireless VerseGrip ready flag is now gated on the initial device-info handshake — previously possible to flip before the device fully announced itself on certain re-attach paths.
  • Runtime changes to keyed-rate-gate-backed settings now take effect on the next hit (was: frozen at first emplace; only new sessions picked up the change).

Potential breaking changes

  • HTTP 404 strings unified across basis, preset, mount, transform, force_gate: "{type} device #{id} not found""no device matches selector '{expr}'". Session 404 likewise.
  • Settings glob devices/inverse*/...devices/*inverse/... for force-scale gain, force-gate gain, control timeout, safeties/expose_in_snapshot. 3.5.0 settings files using the old literal will fail to bind.
  • Settings: serialization globals moved to session/serialization/* (explicit_fields, force_complete_transforms, preview/*). Old serialization/* paths still resolve via deprecated aliases; removal at 4.0.
  • Behaviour: clients using the per-message WS reply as a tick-sync handshake see at most one reply per ms per session under sustained traffic. Full snapshots on config change are unaffected.

Deprecations

None in 3.5.1. The preview master switch is the deprecation plumbing for the upcoming 3.6 silent-to-warn pipeline; the first deprecation pass is scheduled for 3.5.2.