Feature coverage
The four SDKs cover almost the same set of commands. The differences are listed in the table below and in the note under it.
Everything below is documented in the reference.
What the SDKs cover
| Feature | Python | NodeJS | Rust | C |
|---|---|---|---|---|
| Connect, handshake, version check | ✅ | ✅ | ✅ | ✅ |
| List devices (hardware and demo) | ✅ | ✅ | ✅ | ✅ |
| Device capabilities (rates, thresholds, triggers) | ✅ | ✅ | ✅ | ✅ |
| Open / attach / duplicate / list workspaces | ✅ | ✅ | ✅ | ✅ |
Open a .scana file as a workspace | ✅ | ✅ | ✅ | ✅ |
Read a .scana manifest without opening it (file_info) | ✅ | ✅ | ✅ | ✅ |
Shut the server down (shutdown) | ✅ | ✅ | ✅ | ✅ |
| Channels, and lookup by name | ✅ | ✅ | ✅ | ✅ |
| Device info | ✅ | ✅ | ✅ | ✅ |
| Capture start / stop / wait / state | ✅ | ✅ | ✅ | ✅ |
| Per-channel thresholds (P992 probes) | ✅ | ✅ | ✅ | ✅ |
| External trigger loop test, TRIG OUT to TRIG IN (SP259 family) | ✅ | ✅ | ✅ | ✅ |
| Triggers (edge, logic, pulse, steps, external, sequence) | ✅ | ✅ | ✅ | ✅ |
| Transitions, edge seeking, level at a sample | ✅ | ✅ | ✅ | ✅ |
| Baud-rate detection | ✅ | ✅ | ✅ | ✅ |
| Decoders: discover, add, configure, control | ✅ | ✅ | ✅ | ✅ |
| Decoded packets, groups and items | ✅ | ✅ | ✅ | ✅ |
| Hex view and hex search | ✅ | ✅ | ✅ | ✅ |
| Memory View of a decoder | ✅ | ✅ | ✅ | ✅ |
| Markers and measurements | ✅ | ✅ | ✅ | ✅ |
| Pattern generator (SP1000G series) | ✅ | ✅ | ✅ | ✅ |
| Stop a pattern generation, pattern duration | ✅ | ✅ | ✅ | ✅ |
| Generation rows and signal builders (SQ series) | ✅ | ✅ | ✅ | ✅ |
| Generation and mixed capture runs, channel direction, differential pairs (SQ series) | ✅ | ✅ | ❌ | ❌ |
| Script library (install, import, create, rename, delete) | ✅ | ✅ | ✅ | ✅ |
Save a .scana file | ✅ | ✅ | ✅ | ✅ |
| CSV export (samples, raw, packets, hex) | ✅ | ✅ | ✅ | ✅ |
| Event stream and server log | ✅ | ✅ | ✅ | ✅ |
The Rust and C capture requests have no operation, generator_samples,
generator_loop, channel_io or differential field. From Rust or C you can
prepare the generation rows of an SQ device and read them back, but you cannot
start a generation or mixed run, set a channel's direction or pair channels
as differential. Use Python or NodeJS for those.
Two device families drive outputs, each in its own way:
- The SP1000G series (SP1018G, SP1036G, SP1054G) runs a pattern generator script. See Pattern generator.
- The SQ series (SQ25, SQ50, SQ100, SQ200) replays generation rows: you
write them with
workspace.generation(directly or through builder scripts), then run the capture withoperation="generation"oroperation="mixed".
On an SE254, SP209 or SP259 the calls exist but the hardware has no outputs to drive.
How each SDK reads
The same coverage does not mean the same code.
| Shape | |
|---|---|
| Python | Synchronous and blocking. Requests and results are pydantic models. Device, ServerInfo, Option, GenerationState and the bulk records (Item, HexPage, MemPage) are frozen dataclasses, and Edge is a named tuple. |
| NodeJS | async/await for every call that waits for an answer, with async iterators over bulk data. Calls that only send a command are synchronous and return nothing (see below). |
| Rust | async with ?, typed errors, and builders for the request payloads. Delays are Duration values. |
| C | Handles and status codes. Configuration comes back as JSON to free with ss_string_free; bulk records come back as a batch to free with _free. |
In NodeJS, these calls are synchronous: capture.start(), capture.stop(),
workspace.close(), workspace.attach_device(), workspace.set_ui_state(),
markers.move_to(), markers.remove(), markers.clear(),
measures.set_kinds(), measures.move_to(), measures.remove(),
measures.clear(), decoder.relaunch(), decoder.pause(), decoder.remove(),
decoders.remove(), decoders.clear(), pattern.set_enabled(),
pattern.set_generate_on_trigger(), pattern.remove(), pattern.resume(),
pattern.stop_generation(), generation.remove_builder() and
server.shutdown(). Putting await in front of them is harmless.
Exported constants and types
Each package exports the values the API checks against, so a script can use them instead of copying lists.
| Name | Value | Python | NodeJS | Rust | C |
|---|---|---|---|---|---|
MEASURE_KINDS | The 18 measurement names | ✅ | ✅ | ✅ (MeasureKind::ALL) | ss_measure_kinds() |
STANDARD_MEASURE_KINDS | time_total, freq_avg, freq_min, freq_max: what a measurement computes when you name none | ✅ | ✅ | MeasureKind::STANDARD | |
MeasureKind | The type of one measurement name. In Rust an enum with as_str() and from_name() | ✅ | ✅ (type) | ✅ | |
RUNNING_STATES | Capture states that count as running: preparing, configuring, purging, pretrigger, waiting_trigger, sampling | ✅ | ✅ | ✅ | |
EXPORT_SOURCES | samples, raw, packets, hex | ✅ | ✅ | ✅ | |
SEQUENCES | a_or_b, a_then_b, b_then_a, a_and_b | ✅ | ✅ | ✅ | |
PROTOCOL_VERSION | The protocol version the client speaks (8) | ✅ | ✅ | ✅ | |
PAGE | Rows per request when paging packets, items and hex: 5000 | ✅ | ✅ | ✅ | |
EDGE_PAGE | Edges per request when paging transitions: 200 000 | ✅ | ✅ | ✅ | |
| Default delays | DEFAULT_WAIT (capture, 300 s), DEFAULT_IO_WAIT (save, open, export, 600 s) | ✅ | DEFAULT_WAIT_MS, DEFAULT_IO_WAIT_MS, DEFAULT_TIMEOUT_MS | ✅, plus DEFAULT_DECODE_WAIT, DEFAULT_BUILD_WAIT, DEFAULT_TIMEOUT | |
Edge, Item, HexPage, MemPage | The records of the bulk reads: transitions, raw items, hex pages, Memory View pages | ✅ | ✅ (types) | ✅ | ss_edge, ss_items, ss_hex, ss_mem |
In NodeJS, every type generated from the protocol (requests, answers, events)
is also available from the @ikalogic/scanastudio/protocol subpath. In Rust
they are under scanastudio_client::proto.
Out of scope
The ScanaStudio application does a few things that no client library exposes, or that the SDKs expose but this documentation does not cover:
- Waveform rendering: the pixel columns the ScanaStudio display draws from.
- Signal overlay: the drawing tools that let the application correct a capture by hand.
- Server settings and diagnostics: autosave policy, proxy configuration, and crash reporting.
- Firmware updates. Use ScanaStudio for those. The hardware and firmware
versions are available through
device_info(). - Production-line commands (
server.production.set_device_serial()andserver.production.ftdi_reset()), Python only. They program a device during manufacturing and are not meant for test benches. - Editor and script-metadata calls used by the application:
cancel_io,clear_log,set_scripts_dir,script_detailsandopen_script_in_editor.