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> --jsonstream 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 streamSelect 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.ndjsonAn 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, withready,sample, andendrecords containingpairId, 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:
| Event | Use it for |
|---|---|
streamStart | First supported mode and the stream's units. |
workoutState | Current workout state and mode-specific configuration. |
rep | One pull or recovery measurement for a physical repetition. |
progress | Current set progress and aggregate totals. |
setSummary | The result of one set. |
workoutSummary | Workout totals. |
dataQuality | Transport drops or decode errors. |
connectionLost / reconnected | A connection recovery boundary. |
streamEnd | Termination 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
- Count completed repetitions only from
repevents wheredirectionispullandvalidistrue. Arecoveryevent is not a second repetition. - A physical repetition can produce pull and recovery events with the same
setIndexandrepIndex. The two directions can arrive in either order; pair them by both indexes when both phases are needed. rep.repIndexis one-based.progress.repIndexis the number of completed reps in the current set and may be0before the first rep.- Use
setSummary.repsandworkoutSummary.repsfor aggregate counts. - 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. sequencedescribes output order, not a device clock. Usetimestampfor event time and elapsed-time calculations.- Treat
dataQuality,connectionLost, andreconnectedas data boundaries. Partition records byconnectionId. Do not pair events across different connection IDs or synthesize missing repetitions. streamEnd.complete: truemeans the subscriber stopped normally; it does not mean the workout was completed.complete: falsemeans the subscription ended abnormally and the recorded data is incomplete.- EOF without
streamEndis also an abnormal termination. - 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(lbsorkg). - Distance uses
mm.rep.distanceMmis directional distance;pullDistanceMmis cumulative pull distance and is not current cable length. - Power uses
W. Work usesJwhenrep.totalWorkJis present. - Duration and elapsed time use
ms. Damperlevelis 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.totalWorkJis 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.pullVolumeis pull-direction volume. It is always present onworkoutSummaryand may be omitted fromprogressorsetSummary.
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
streamsubscribes 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 statusremains available; there is no publicvoltra pingcommand. voltra disconnectends 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.
VOLTRA Getting Started
Guide first-time Cortex users from installation to first successful training session. **Happy path only.** Use when the user is new to Cortex, asks "how do I start", wants to set up Cortex for the first time, configure their API key, scan for devices, or connect to a device for the first time. If installation or PATH fails, or any command errors out, jump to `voltra-cli-troubleshooting` instead.
VOLTRA Device Status
Read and summarize VOLTRA device state through Cortex. **Read-only — does not issue control commands.** Use when the user asks about connected devices, battery level, training mode, power/load state, cable zero position, saved devices, nearby devices, or wants an AI agent to inspect device readiness before taking action. To actually change a setting or start training, use `voltra-device-training`.