Skip to main content

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​

FeaturePythonNodeJSRustC
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✅✅✅✅
Where the SDKs differ

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 ways to generate signals

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 with operation="generation" or operation="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
PythonSynchronous 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.
NodeJSasync/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).
Rustasync with ?, typed errors, and builders for the request payloads. Delays are Duration values.
CHandles 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.

NameValuePythonNodeJSRustC
MEASURE_KINDSThe 18 measurement names✅✅✅ (MeasureKind::ALL)ss_measure_kinds()
STANDARD_MEASURE_KINDStime_total, freq_avg, freq_min, freq_max: what a measurement computes when you name none✅✅MeasureKind::STANDARD
MeasureKindThe type of one measurement name. In Rust an enum with as_str() and from_name()✅✅ (type)✅
RUNNING_STATESCapture states that count as running: preparing, configuring, purging, pretrigger, waiting_trigger, sampling✅✅✅
EXPORT_SOURCESsamples, raw, packets, hex✅✅✅
SEQUENCESa_or_b, a_then_b, b_then_a, a_and_b✅✅✅
PROTOCOL_VERSIONThe protocol version the client speaks (8)✅✅✅
PAGERows per request when paging packets, items and hex: 5000✅✅✅
EDGE_PAGEEdges per request when paging transitions: 200 000✅✅✅
Default delaysDEFAULT_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, MemPageThe 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() and server.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_details and open_script_in_editor.