Beyond Cortex

VOLTRA User Live Training Stream

Use when a user wants live VOLTRA training telemetry for real-time analysis, dashboards, control-room displays, recording/replay, or custom pipelines. Subscribe through the daemon-owned NDJSON stream; do not use this for workout history or device control.

Use voltra stream in Cortex when the user needs live measurements from a connected VOLTRA device. It is the unified live-stream entry point: an independent device emits voltra.training.v7, while a confirmed Twin automatically emits voltra.training.twin.v1. The command writes one complete JSON object per line (NDJSON) to stdout and flushes each record as it arrives.

Consumers must dispatch by the record's schema; do not assume that every invocation of voltra stream is v7.

This skill covers live telemetry for movement displays, workout dashboards, recording, replay, and custom pipelines. Use voltra-workout-data for completed workout history, voltra-device-status for a point-in-time snapshot, and voltra-device-training for commands that change device state or resistance.

Supported modes

The public stream currently provides mode-specific training events for:

  • weightTraining, including chains, eccentric, assist, and burnout settings;
  • resistanceBand;
  • damper;
  • isokinetic (constant-velocity training) for the independent-device v7 stream.

For an independent device, Isometric, Professional/Custom Curve, Rowing, Ski, and Sled Pull are not part of the v7 event contract yet. Cortex keeps the subscription active for those modes but does not emit mode-specific training events until a supported mode is observed. If the device starts unsupported, streamStart is delayed. A normally stopped subscription still emits streamEnd, which may be the only public event.

For a confirmed Twin, the same voltra stream command selects the separate voltra.training.twin.v1 contract. Twin records carry logical master/slave identity, topology, local/peer data, and quality fields; they are not v7 single-device workout events.

This stream does not include Concept2 Logbook data. For completed rowing or skiing history, use voltra-workout-data, which distinguishes VOLTRA Cardio Rowing/Skiing from Concept2 Rowing/Ski and can present a clearly labeled combined summary when requested.

If a user changes to an unsupported mode while streaming, suppress mode-specific training output until a supported mode is observed again. workoutState then resumes with the same streamId and sequence.

Prerequisites

Cortex requires a persisted VOLTRA API key for device commands, including stream. If setup is not already confirmed, tell the user to configure it without exposing the key in logs or responses:

voltra config set-api-key "<VOLTRA_API_KEY>"

The device session must already be owned by the Cortex daemon:

voltra scan --json
voltra connect <DEVICE_ID> --json

stream does not scan or connect directly. If scan, connection, or daemon errors persist, load voltra-cli-troubleshooting. If the user is not set up yet, load voltra-getting-started.

Quick start

Print live NDJSON to stdout:

voltra stream

Select a connected device explicitly when needed:

voltra stream --device-id <DEVICE_ID>

For a confirmed Twin, omit the selector in the normal flow so Cortex resolves the logical master. If multiple connected Twin sessions need disambiguation, pass the master with --device-id <MASTER>; never pass the slave selector. --report-rate applies only to the independent-device v7 stream.

Record the stream for replay:

voltra stream --output .\training.ndjson

An existing output file is replaced. Check the path first if the previous recording must be preserved.

Stdout and --output contain only NDJSON. Diagnostics go to stderr. Do not add --json. Closing the subscriber stops the realtime subscription but leaves the daemon's device session connected. voltra disconnect ends the active stream as part of disconnecting the session. Only one stream subscriber can be active at a time. Twin telemetry uses the same NDJSON and daemon-session boundaries.

Public contract

voltra stream selects one of two public contracts based on the connected topology:

  • Independent device: voltra.training.v7, documented below and in the v7 schema reference.
  • Confirmed Twin: voltra.training.twin.v1, with ready, sample, and end records containing pairId, master/slave identity, topology, local/peer data, and quality fields.

For independent-device v7 records, every record contains:

  • event — event name;
  • schema — voltra.training.v7;
  • timestamp — UTC RFC 3339 event time;
  • sequence — output order within this stream;
  • streamId — subscription identifier;
  • deviceId — VOLTRA device identifier;
  • connectionId — connection generation, which changes after reconnect.

The machine-readable contract is in:

The public events are:

EventUse it for
streamStartFirst supported mode and the stream's units.
workoutStateCurrent workout state and mode-specific configuration.
repOne pull or recovery measurement for a physical repetition.
progressCurrent set progress and aggregate totals.
setSummaryThe result of one set.
workoutSummaryWorkout totals.
dataQualityTransport drops or decode errors.
connectionLost / reconnectedA connection recovery boundary.
streamEndTermination status and final quality counters.

The stream is compact workout telemetry, not a raw high-frequency force curve. Raw device notifications, BLE frames, protocol values, and internal aliases are not public fields.

Independent-device v7 example records

Each physical line is a separate event, not an item in a JSON array:

{"event":"streamStart","schema":"voltra.training.v7","timestamp":"2026-09-07T10:00:00.000Z","sequence":1,"streamId":"550e8400-e29b-41d4-a716-446655440000","deviceId":"AA:BB:CC:DD:EE:FF","connectionId":1,"trainingMode":"weightTraining","units":{"weight":"lbs","distance":"mm","velocity":"mm/s","power":"W"}}
{"event":"rep","schema":"voltra.training.v7","timestamp":"2026-09-07T10:00:01.100Z","sequence":2,"streamId":"550e8400-e29b-41d4-a716-446655440000","deviceId":"AA:BB:CC:DD:EE:FF","connectionId":1,"setIndex":0,"repIndex":1,"direction":"pull","valid":true,"distanceMm":480,"peakVelocityMmPerSecond":1230,"peakPowerWatt":612,"volume":40,"durationMs":900}
{"event":"progress","schema":"voltra.training.v7","timestamp":"2026-09-07T10:00:01.200Z","sequence":3,"streamId":"550e8400-e29b-41d4-a716-446655440000","deviceId":"AA:BB:CC:DD:EE:FF","connectionId":1,"setIndex":0,"repIndex":1,"volume":40,"pullDistanceMm":480,"elapsedMs":1200}
{"event":"streamEnd","schema":"voltra.training.v7","timestamp":"2026-09-07T10:05:00.000Z","sequence":4,"streamId":"550e8400-e29b-41d4-a716-446655440000","deviceId":"AA:BB:CC:DD:EE:FF","connectionId":1,"reason":"stopped","complete":true,"droppedEvents":0,"decodeErrors":0}

Values are illustrative. Optional fields are omitted when the device does not provide them. A real stream can contain additional events between these lines.

Independent-device v7 consumption rules

  1. Count completed repetitions only from rep events where direction is pull and valid is true. A recovery event is not a second repetition.
  2. A physical repetition can produce pull and recovery events with the same setIndex and repIndex. The two directions can arrive in either order; pair them by both indexes when both phases are needed.
  3. rep.repIndex is one-based. progress.repIndex is the number of completed reps in the current set and may be 0 before the first rep.
  4. Use setSummary.reps and workoutSummary.reps for aggregate counts.
  5. Missing optional values are omitted, not replaced with zero. Use the value at the event level for volume; do not recompute it by summing unrelated progress and rep events.
  6. sequence describes output order, not a device clock. Use timestamp for event time and elapsed-time calculations.
  7. Treat dataQuality, connectionLost, and reconnected as data boundaries. Partition records by connectionId. Do not pair events across different connection IDs or synthesize missing repetitions.
  8. streamEnd.complete: true means the subscriber stopped normally; it does not mean the workout was completed. complete: false means the subscription ended abnormally and the recorded data is incomplete.
  9. EOF without streamEnd is also an abnormal termination.
  10. This is device telemetry only. It does not create, upload, or reconcile workout History records.

Independent-device v7 data units

  • Load, force, and volume use streamStart.units.weight (lbs or kg).
  • Distance uses mm. rep.distanceMm is directional distance; pullDistanceMm is cumulative pull distance and is not current cable length.
  • Power uses W. Work uses J when rep.totalWorkJ is present.
  • Duration and elapsed time use ms. Damper level is unitless and ranges from 1 to 10.
  • Weight, force, and volume values are rounded to at most two decimal places before emission. Counts and integer distance, velocity, power, work, and duration fields are not padded with decimal places.
  • rep.meanPowerWatt, when present, is device-reported mean power for that direction. rep.totalWorkJ is device-reported directional work and may be omitted. Do not reconstruct mean power from another field or use mechanical work alone to estimate calorie expenditure.
  • pullVolume is pull-direction volume. It is always present on workoutSummary and may be omitted from progress or setSummary.

Independent-device v7 mode-specific fields

workoutState contains:

  • all modes: trainingMode, workoutState, powerEnabled;
  • weightTraining: baseWeight, chainsWeight, eccentricWeight;
  • resistanceBand: resistanceBandWeight;
  • damper: level;
  • isokinetic: targetVelocityMmPerSecond.

Mode-specific fields are omitted when they do not apply.

setSummary and workoutSummary contain counts, distance, volume, duration, rest time, and nested pull/recovery metrics: maxForce, meanForce, maxVelocityMmPerSecond, meanVelocityMmPerSecond, maxPowerWatt, and meanPowerWatt.

Operational boundaries

  • stream subscribes to the existing daemon session; it does not disconnect the device when the subscriber exits.
  • Device-changing commands share the daemon's serialized BLE operation boundary and can run while the stream continues. voltra daemon status remains available; there is no public voltra ping command.
  • voltra disconnect ends the active stream as part of disconnecting the daemon session.
  • The stream is device telemetry only; it does not create or upload History records.
  • Only one live stream subscriber may be active because the daemon-owned notification receiver is single-consumer.