Step 10: Live Monitoring #

Goal: Run tests while monitoring events and instrument data in real time.

Prerequisites #

Start a Station Session #

Open a Python script or Jupyter notebook:

from litmus import connect
 
# Connect to your station (mock mode for this tutorial)
with connect("bench_1", mock=True) as station:
    dmm = station.instrument("dmm")
 
    # Each read is captured to the channel store as the session runs
    voltage = dmm.measure_voltage()
 
    print(f"Session ID: {station.session_id}")
    print(f"Voltage: {voltage}")

This creates a session and records what happens — instrument reads land in the channel store, session and step events in the event store.

Monitor in the UI #

In another terminal:

litmus serve --reload

Open http://localhost:8000 — the operator UI shows live session activity, including:

  • Session metadata (station, UUT, operator)
  • Instrument connections
  • Measurements as they happen
  • Step progress during test runs

Run Tests While Monitoring #

# In another terminal, run tests
pytest tests/ -s

The UI updates in real time as tests execute:

pytest run → events recorded → UI updates live

View the Run in Results #

When pytest finishes, the run lands in the Results history. Open http://localhost:8000/results — each pytest invocation that produced one or more tests appears as a row. The list shows Outcome / Serial / Part Number / Hostname / Project / Phase / Started / Steps / Meas / Ended. There's no filter bar; columns are sortable and a stats strip above the table summarizes the visible runs.

Click any row to drill into the detail view at /results/<run_id>. The detail page is a sticky header card with a tab strip beneath: Overview (run-level summary), Steps (one row per (step_path, vector_index) execution with its outcome and measurement count), Measurements (every value logged with its limit and outcome), and UUT History (this UUT's prior runs).

For the full reference, see Operator UI → Results — list and Operator UI → Results — detail.

See How the Line Is Doing #

After a few runs accumulate, the /metrics page becomes the go-to "is the bench healthy" view. A filter bar (Phase / Part / Station / Lot / Since / Until) sits above a tab strip with six analytical lenses:

TabWhat it shows
YieldFirst-pass yield, final yield, run / failure counts, a yield trend chart, and time stats
ParetoFailure counts grouped by Part, Step, or Measurement (the group-by is a control on the tab)
CpkPer-measurement process capability, ranked worst-first
RetestTime-bucketed retest rate — how many serials needed more than one attempt that period
Time lossWall-clock time spent on failed / errored runs per period
AssetsPer-instrument time share — Role / Resource / Sessions / Connected (s) / Share

For the full reference, see Operator UI → Metrics. For the diagnostic recipe behind the Retest signal, see Find flaky tests.

Query Historical Data #

After tests complete, query the results:

# Via HTTP API
curl http://localhost:8000/api/sessions
curl "http://localhost:8000/api/events?session_id=YOUR_SESSION_ID"
curl http://localhost:8000/api/channels

Or with the MCP tools:

litmus_sessions()
litmus_events(session_id="...")
litmus_channels(channel_id="dmm.voltage")

Channel Data from Instrument Reads #

Instrument reads route to the ChannelStore — Litmus's time-series store for sample data, both scalar readings and arrays like waveforms. A ChannelStarted event marks each channel; the event carries a channel:// reference (a URI string) pointing at the channel, not the samples themselves:

with connect("bench_1", mock=True) as station:
    scope = station.instrument("scope")
    waveform = scope.waveform()
    # Samples land in the ChannelStore under a channel id like ``scope.waveform``;
    # the event holds a ``channel://`` URI pointing to them.

Query channel data by channel id:

curl "http://localhost:8000/api/channels/scope.waveform?max_points=500"

See also: Step 12: Continuous Monitoring — streaming into ChannelStore directly from an interactive script using litmus.channels.stream.

How live monitoring works #

When you connect to a station, Litmus records every instrument read and step result as it happens and makes it available to the operator UI in real time. Large arrays like waveforms are downsampled before display, so big captures still draw quickly.

For the mechanics, see Data stores and Flight streaming.

Step 9: Production Ready | Tutorial index

Next Steps #

Tutorial · Step 11 of 13