Skip to content

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 08:28
· 25 commits to main since this release

First release. This entry describes what the package contains rather than how it
got here: nothing before this was installable from an index, so a per-change
history would be a list of deltas against states no one could have been running.
The development history is in the git log.

Alpha in the trove classifier and 0.x in the version: the API may still break.

Library

  • Scope, a typed high-level API over VISA (pyvisa / pyvisa-py). Channels,
    timebase, acquisition, run/stop/single, autoscale and instrument identity, with
    the densely-parameterized subsystems as their own objects: scope.trigger,
    scope.measure, scope.generator, scope.waveform and scope.digital.
  • Every call is validated against the scope's own firmware definitions -
    arity, value types and enum spellings - so a bad argument is refused locally
    instead of becoming a silent entry in the instrument's error queue. Short SCPI
    spellings are accepted wherever a mnemonic is, and replies are canonicalized
    back to the published spelling.
  • Complete typed trigger control across all 20 trigger modes, as a
    discriminated union of per-mode configs.
  • Batched measurements: up to 32 waveform, digital-timing or two-source
    comparison requests per call, plus accumulated statistics and percentage or
    absolute reference levels.
  • Waveform acquisition in three depths - NORMal (the 1000 displayed
    points), TRACe (the displayed window at acquisition resolution) and RAW
    (the whole acquisition memory). inspect computes complete statistics with an
    optional bounded preview and retains nothing; acquire keeps every point for
    values, summarize and find_edges, which are also available as pure
    functions in pymso5000.api.waveform_analysis. Deep memory is transferred in
    windows, with statistics accumulated in that single pass.
  • Both built-in generators, including modulation, sweep and burst modes and
    arbitrary waveform upload.
  • saved_setup(), a context manager that exports the instrument setup and
    restores it on either exit path - the rollback point for anything broad, such
    as autoscale(). It does not cover the generator, which is documented on the
    API rather than left to be discovered.
  • An error taxonomy: ScopeError carrying a kind and a retryable flag,
    specialized into usage, policy, state, command, transport, timeout, reply and
    framing errors, so a caller can tell a bad argument from a dropped link from an
    instrument in the wrong state without matching on message text. Setters that
    apply several settings report what already landed in partial, because the
    instrument does not roll back.
  • ScpiCatalog and CommandDocs search, resolve and document the full
    2236-command firmware set and its 784 compatibility aliases, and need no
    connection at all.
  • MSO5000, the low-level client: serializes a command and parses the reply,
    including IEEE 488.2 binary blocks for screenshots, waveforms and setups.
    Message-based VISA transports are supported generally - VXI-11, HiSLIP, USBTMC,
    GPIB, raw socket and serial - with framing decided from the resource name.
  • SCPI definitions are bundled, and are the only copy the package ships. With
    the firmware extra they can instead be extracted from a Rigol .GEL image by
    an in-tree UBI/UBIFS reader; the test suite extracts one and asserts the result
    matches the shipped definitions byte for byte.
  • Typed: py.typed is shipped and the package is checked under pyright
    strict.

MCP server (pymso5000[mcp])

  • A stdio MCP server, pymso5000-mcp, exposing the instrument to AI agents:
    screenshot and touchscreen/key/knob control, acquisition and setup, batched
    measurements, the two-path waveform workflow, and generic SCPI search, describe
    and execute for anything the typed tools do not cover.
  • Structured output schemas and tool annotations on every tool, with the
    instrument's own enum and range constraints published in the input schemas.
  • Process-local retained stores for waveform captures and instrument setups,
    addressed by opaque bearer handles with quotas and a TTL. Samples and setup
    blobs are reachable only through bounded tools, never inlined into model
    context.
  • Six direct-SCPI risk categories - storage, connectivity, security,
    calibration, licensing, firmware - all disabled by default and matched on
    the resolved canonical command, so a short form cannot bypass one. Raw
    touch/key/knob control is deliberately a trusted front-panel-equivalent lane,
    which the README states rather than leaves to be inferred.
  • Resources scpi-doc://command/{command}, scope://state,
    oscilloscope://captures/{capture_id} and oscilloscope://setups/{setup_id},
    and prompts characterize_signal and debug_no_trigger.
  • Audit logging to stderr for every call - tool, arguments, duration, and
    outcome or error kind - leaving stdout to carry only the JSON-RPC stream.

Distribution

  • pip install pymso5000, with the MCP server behind the mcp extra and
    firmware extraction behind firmware. The library imports and works with
    neither installed.
  • CI runs ruff, ruff format, pyright and the test suite under a coverage floor on
    Linux, and the suite alone on macOS, Windows and free-threaded CPython. It
    builds both artifacts, installs each, runs the unpacked sdist's own test suite
    from inside itself, smoke-tests the installed console script, and builds the
    Nix derivation.
  • Releases are published to PyPI from a tagged commit through Trusted Publishing,
    so no API token exists to leak, and are attested with build provenance.