Skip to main content

Saving and exporting

Writing a workspace to disk: a .scana file that keeps everything, or a CSV of one part of it. Both sit directly on the workspace.

The server writes the file

Every path on this page is resolved by the server, on the server's machine and with the server's permissions, not by your script. Against a remote server, a local path means nothing and the file lands on the far end. See Remote and shared instruments.

save​

Writes the whole workspace to a .scana: the captured data, the decoders and their configuration, the markers and the measurements.

workspace.save("/data/run-42.scana", timeout=600.0)

workspace.path # where it was saved, or None
workspace.dirty # True when there are unsaved changes

Opening a .scana​

Reopen one later with open(). No device needed.

open() returns once the capture is loaded

open() waits until the file is loaded. When it returns the capture is in the workspace, so there is no polling loop to write:

workspace = server.open("/data/run-42.scana")
workspace.capture.last_sample # the recording, not 0

A file that cannot be read, or that takes longer than the timeout, raises rather than handing back an empty workspace: IoError in Python and NodeJS, Error::Io in Rust, and a NULL handle with ss_last_error() in C.

export_csv​

Writes part of the workspace as CSV.

# Raw samples for two channels.
workspace.export_csv(
"/data/samples.csv",
source="samples",
channels=[0, 1],
)

# The decoded packets of one decoder.
workspace.export_csv(
"/data/packets.csv",
source="packets",
instances=[i2c.instance_id],
)

# A European-locale CSV, over a marker range.
workspace.export_csv(
"/data/run.csv",
source="hex",
separator=";",
decimal_comma=True,
from_marker=first,
to_marker=second,
)

The four sources:

sourceWhat it writes
samplesRaw logic samples for the channels you name. The largest by far.
rawThe decoders' item rows — every element they produced, with its span.
packetsThe Packet View: decoded packets with title and content.
hexThe Hex View: the byte stream the decoders produced.

Options:

OptionMeaning
channelsWhich channels to write. samples only.
instancesWhich decoder instances to write. The three decoded sources.
separatorField separator. Defaults to ,.
decimal_commaWrite 0,5 rather than 0.5, for European spreadsheets.
from_marker, to_markerRestrict the export to a marker range.
The workspace is frozen while it exports

A CSV export freezes the workspace: any command that would change it is refused with a Busy error until the export finishes. That includes commands from other clients, so the ScanaStudio window will look stuck. Exporting a long capture takes a while, which is why the default timeout is 600 s.

A second export issued immediately after the first writes nothing

export_csv returns as soon as the export finishes, but the workspace currently stays frozen a moment longer. A second call made straight away is refused with busy, and in the Python and NodeJS SDKs the refusal is not raised: the call returns normally and no file appears.

workspace.export_csv("/tmp/packets.csv", source="packets", instances=[i2c.instance_id])
workspace.export_csv("/tmp/samples.csv", source="samples", channels=[0, 1])
# packets.csv exists. samples.csv does not, and nothing was raised.

Until this is fixed, export once per run where you can. Otherwise leave a pause between calls and check that each file exists before relying on it.

save(), open() and export_csv() block until the server is finished and cannot be cancelled. The timeout is the only way out: give the call a budget you are willing to wait, and handle the Timeout if it runs over.

ui_state​

A workspace carries a blob of client view state (zoom, cursors, whatever your own front end wants to remember). The server never reads it; it is written into the .scana and comes back with it.

workspace.set_ui_state('{"zoom": 4}', mark_dirty=False)
workspace.ui_state # the state this workspace was OPENED with
Reading it back does not return what you just wrote

ui_state reports the state the workspace was opened with: the server sends it when you attach and when a .scana is loaded. It is not an echo of set_ui_state. A value you have just written reads back here only after the workspace has been saved and reopened, or attached to afresh. Keep your own copy in memory if you need to read it during a session.

Pass mark_dirty of false for a change the user would not call unsaved work, such as moving a cursor rather than editing the capture.

Errors: file operations raise IoError (Error::Io in Rust, ss_status_Failed with ss_last_error() in C) for a path the server cannot write, a disk that filled up, or a cancellation.