Workspace and devices
A workspace is one working session: a device, a capture, the decoders attached to it and its annotations. Every other API in this reference hangs off it.
- Python
- NodeJS
- Rust
- C
# Saving and exporting are on the workspace itself, not a sub-API.
workspace.save(...)
workspace.export_csv(...)
workspace.capture # capture control
workspace.data # transitions, packets, hex
workspace.decoders # protocol decoders
workspace.markers # markers
workspace.measures # measurements
workspace.pattern # pattern generator
workspace.events # the event stream and the log
workspace.capture;
workspace.data;
workspace.decoders;
workspace.markers;
workspace.measures;
workspace.pattern;
workspace.events;
workspace.capture();
workspace.data();
workspace.decoders();
workspace.markers();
workspace.measures();
workspace.pattern();
workspace.events();
/* C has no sub-APIs: every function takes the workspace handle. */
ss_capture_run(workspace, /* ... */);
ss_data_transitions(workspace, /* ... */);
id and device_name​
- Python
- NodeJS
- Rust
- C
workspace.id # the id attach() takes
workspace.device_name # "SE254" or "SP259 (sn 1004250000604)"
workspace.id;
workspace.device_name;
workspace.id(); // u64
workspace.device_name(); // String
uint64_t id = ss_workspace_id(workspace);
char *name = ss_workspace_device_name(workspace); /* "SE254", "SP259 (sn ...)" */
if (name) { printf("%s\n", name); ss_string_free(name); }
channels​
The device's channels, in order. Index in this list is the channel number every other call takes.
- Python
- NodeJS
- Rust
- C
for index, channel in enumerate(workspace.channels):
print(index, channel.name, channel.ch_label, channel.color)
workspace.channels.forEach((channel, index) => {
console.log(index, channel.name, channel.ch_label, channel.color);
});
for (index, channel) in workspace.channels().into_iter().enumerate() {
println!("{index} {} {}", channel.name, channel.ch_label);
}
/* A JSON array of {name, color, ch_label}, in device order. The index into
it is the channel number every other call takes. */
char *channels = ss_workspace_channels(workspace);
if (channels) {
printf("%s\n", channels);
ss_string_free(channels);
}
Example output. The four channels of an SE254: index, signal name, probe label, colour:
ch 0 UART TX CH1 #006EF5
ch 1 UART RX CH2 #FFC139
ch 2 I2C SCL CH3 #D80000
ch 3 I2C SDA CH4 #00E700
The index is the channel number every other call takes; CH1…CH4 is what is
printed on the probe, and the colour matches the physical wire.
Fields: name (the signal name), ch_label (the label printed on the
probe), color.
channel​
Looks a channel up by name and returns its number. Matches the signal name or the probe label, case-insensitively.
- Python
- NodeJS
- Rust
- C
scl = workspace.channel("I2C SCL") # -> 2
# Raises KeyError if the device has no such channel.
const scl = workspace.channel('I2C SCL');
// Throws RangeError if the device has no such channel.
// Errors if the device has no such channel.
let scl: u16 = workspace.channel("I2C SCL")?;
int32_t scl = ss_workspace_channel(workspace, "I2C SCL"); /* -1 if there is none */
Looking channels up by name is what lets one test script run on an SE254, an
SP259 and an SP1000G without an if per device. Hard-coded channel numbers
break when the bench changes.
attach_device​
Accepts the device the server offered after a .scana was opened, so a
file-loaded workspace can capture again.
- Python
- NodeJS
- Rust
- C
workspace.attach_device("SP259-000123")
workspace.attach_device('SP259-000123');
workspace.attach_device("SP259-000123")?;
ss_workspace_attach_device(workspace, "SP259-000123");
device_info​
Everything the attached device says about itself: hardware and firmware versions, temperatures, PLL / DDR / HyperRAM health, the probes it sees.
- Python
- NodeJS
- Rust
- C
info = workspace.device_info() # timeout defaults to 60 s
for row in info["rows"]:
print(row)
// Opens the device, so it fails while a capture is running.
const info = await workspace.device_info(); // timeout_ms = 60_000
// Opens the device, so it fails while a capture is running.
let info = workspace.device_info().await?; // serde_json::Value
/* Opens the device, so it fails while a capture is running. */
char *info = ss_workspace_device_info(workspace);
if (info) {
printf("%s\n", info);
ss_string_free(info);
}
Reading device info opens the hardware, so it fails while a capture is running. Ask for it before you start, or after it is done.
Use ScanaStudio to update a device's firmware. The hardware and firmware
versions are in device_info() above.
close​
Ends the workspace on the server: the capture is aborted, the decoders stop and the data is freed.
- Python
- NodeJS
- Rust
- C
workspace.close()
workspace.close(); // permanent, and it affects every attached client
workspace.close()?; // permanent, and it affects every attached client
ss_workspace_close(workspace); /* ends it on the server */
ss_workspace_free(workspace); /* releases the local handle */
There is no undo, and it affects every client attached to that workspace, including the ScanaStudio window if somebody has it open.
If you only want your script to stop watching, close the connection instead and leave the workspace running.
ss_workspace_close() ends the session on the server. ss_workspace_free()
only releases your handle. Call free on every handle; call close only when
you mean to destroy the session.