Beyond Cortex
Cortex References

Twin & Dual-Device Connections

Connect two VOLTRA devices independently, pair them as Twin, and choose the correct status, control, and telemetry commands.

Two different two-device workflows

Cortex has two separate ways to work with two VOLTRA devices:

WorkflowWhat it meansData and control
Independent connectionsTwo physical devices are connected to the daemon as separate sessions.Each device has its own status, commands, stream, and workout data.
TwinTwo already-connected devices are paired into one logical master/peer topology.The master owns the logical Twin, Twin telemetry, and Twin History context.

Connecting two devices does not automatically create a Twin. Complete the physical connections first, then run the Twin pairing command. When exactly two devices are connected, the command can choose roles from connection order: the first-connected device becomes the master.

Connect two devices independently

The current Cortex connection model supports up to two independent physical device sessions. Both devices must be nearby, powered on, and visible to the Bluetooth adapter.

voltra scan --all --json
voltra connect <DEVICE_A> --json
voltra connect <DEVICE_B> --json

Inspect the daemon and address each device explicitly:

voltra daemon status --json
voltra status --device-id <DEVICE_A> --json
voltra status --device-id <DEVICE_B> --json

Device-scoped control commands also accept --device-id:

voltra set-mode weight-training --device-id <DEVICE_A>
voltra set-weight 20 --device-id <DEVICE_A>
voltra set-mode weight-training --device-id <DEVICE_B>
voltra set-weight 20 --device-id <DEVICE_B>

Without an explicit selector, a device command uses the daemon's active device. Use --device-id when two devices are connected so a command cannot be sent to the wrong session.

Disconnect one device without ending the other session:

voltra disconnect --device-id <DEVICE_A> --json

The third physical connection is rejected after two sessions are active. If a second connection returns already connected ... Run: voltra disconnect, the installed Cortex build predates independent dual-device sessions. Update to a build that includes this capability, stop the background daemon, and retry:

voltra update
voltra daemon stop --json

Pair the sessions as Twin

Twin pairing requires both devices to be connected, compatible, and idle. You can either let Cortex use connection order, or explicitly choose one device as the master and the other as the slave. Do not start pairing while either device is training.

Check the master's current topology before pairing:

voltra twin status --master <MASTER> --json

Pair the two sessions:

voltra twin pair --json

With exactly two connected devices, the first-connected device becomes the master. To override that order, provide both selectors:

voltra twin pair --master <MASTER> --slave <SLAVE> --json

voltra twin connect is a strict alias for voltra twin pair and follows the same connection-order selection:

voltra twin connect --json

To override the order with the alias, provide both selectors:

voltra twin connect --master <MASTER> --slave <SLAVE> --json

The pairing flow confirms the peer identity, establishes the Twin topology, and persists the pair identity locally. Two successful voltra connect commands are not enough to claim that a Twin exists; use voltra twin status and report the explicit topology state.

Twin ownership and training boundaries

The master owns the logical Twin and its History context. Use the master in Twin-specific commands. Once the Twin is confirmed, the connected master is the default target for status, finish-training, unload, and the Twin commands. Do not pass the slave ID to ordinary training commands. Use --master only when several connected sessions or pairs make the target ambiguous; it is an optional disambiguation selector.

The daemon-backed status JSON includes topology with the Twin kind, state, role, masterDeviceId, and slaveDeviceId. A one-shot direct status can only report the master-owned device and topology fields returned by the device's EP_STATUS response. During a confirmed Twin, do not pass the slave selector: the slave has no independent live session. For example:

voltra status --json

Confirmed Twin training supports:

  • Weight Training
  • Resistance Band
  • Damper
  • Isokinetic
  • Isometric
  • Rowing
  • Skiing

Custom Curve and Sled Pull are not supported in Twin mode. Do not retry those commands while paired; unpair first if the user needs a single-device mode.

If twin status reports a pairing or degraded state, do not treat the two physical sessions as a healthy Twin. Resolve the reported topology state before starting or resuming Twin training.

Twin telemetry

voltra stream is the unified telemetry command. It does not merge two independent sessions: an independent device produces voltra.training.v7, and a confirmed Twin automatically produces the logical voltra.training.twin.v1 stream.

For a confirmed Twin, use it without a selector in the normal flow:

voltra stream --output ./twin.ndjson

If multiple Twin pairs are connected, select the logical master with voltra stream --device-id <MASTER>. Never select the slave. The command uses the voltra.training.twin.v1 NDJSON contract; it is a telemetry command, not a History upload command. Do not pass --json; it already writes one JSON event per line.

If the pair becomes degraded or the peer cannot be revalidated, stop and report the daemon error instead of silently treating the stream as a single-device session.

Unpair and clean up

When the devices are already paired as a Twin, control the master only. The slave rejects direct control commands. The normal cleanup is:

voltra finish-training --json
voltra twin unpair --json

Do not run finish-training against <SLAVE>. twin unpair refreshes both sessions and checks that both devices report trainingMode=none and powerEnabled=false. If it reports that a device is still in a workout or loaded, unload the master and retry the two-command cleanup:

voltra unload --json
voltra finish-training --json
voltra twin unpair --json

If more than one Twin pair is connected, add --master <MASTER> to the Twin commands to select the intended pair. Do not use the slave ID as a selector.

After unpairing, the devices return to independent physical sessions. They can be inspected or disconnected separately:

voltra status --device-id <MASTER> --json
voltra status --device-id <SLAVE> --json
voltra disconnect --device-id <MASTER> --json
voltra disconnect --device-id <SLAVE> --json