arena-interface is a small typed Python package and CLI for controlling the
Reiser Lab ArenaController firmware over serial or Ethernet and for collecting
host-side benchmark results that can be compared with firmware-side PERF_* QS
records.
The distribution name is arena-interface and the import package is
arena_interface:
from arena_interface import ArenaInterfaceCreate a virtual environment and install from PyPI:
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install arena-interfaceOn Windows PowerShell:
py -m venv .venv
.\.venv\Scripts\Activate.ps1
py -m pip install --upgrade pip
py -m pip install arena-interfaceFor local development without Pixi:
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m pytest -qIf you use Pixi instead, run pixi install. Pixi will create or refresh
pixi.lock from pyproject.toml.
from arena_interface import ArenaInterface
ai = ArenaInterface(debug=True)
ai.set_ethernet_mode("192.168.10.104")
ai.all_on()
ai.all_off()
ai.switch_grayscale(1)
ai.set_refresh_rate(200)
stats = ai.get_perf_stats()
len(stats), stats.hex()[:64]
ai.show_pattern_frame(pattern_id=10, frame_index=0, frame_rate=200)
ai.update_pattern_frame(1)
ai.update_pattern_frame(2)
ai.all_off()
ai.close()from arena_interface import ArenaInterface
with ArenaInterface() as ai:
ai.set_serial_mode("/dev/ttyACM0")
ai.all_on()
ai.all_off()On Windows, use a COM port such as COM3 instead of /dev/ttyACM0.
The console entry point is arena-interface.
arena-interface --ethernet 192.168.10.104 all-on
arena-interface --ethernet 192.168.10.104 all-off
arena-interface --ethernet 192.168.10.104 set-refresh-rate 200
arena-interface --ethernet 192.168.10.104 switch-grayscale 1
arena-interface --ethernet 192.168.10.104 get-perf-stats
arena-interface --ethernet 192.168.10.104 reset-perf-statsSerial examples:
arena-interface --serial /dev/ttyACM0 all-on
arena-interface --serial /dev/ttyACM0 all-offPowerShell:
arena-interface --serial COM3 all-on
arena-interface --serial COM3 all-offexport ARENA_ETH_IP=192.168.10.104
arena-interface all-on
arena-interface all-off
arena-interface benchPowerShell equivalent:
$env:ARENA_ETH_IP = "192.168.10.104"
arena-interface all-on
arena-interface all-off
arena-interface benchThis repository uses a modern src/ layout and a single pyproject.toml as
its packaging and tooling source of truth.
src/arena_interface/: importable package, version metadata, and CLItests/: lightweight tests that do not require hardwarescripts/: developer helper scripts, including benchmark matrix and performance summary helperstools/: repository-local helper tools such as the QSPY/QTools wrapperpatterns/: example pattern files for streaming tests.github/workflows/: CI and PyPI publishing automationpyproject.toml: package metadata, tool configuration, and Pixi manifestMANIFEST.in: explicit source-distribution file list for non-package assets
The package version lives in src/arena_interface/__about__.py; setuptools
reads that value dynamically so wheel, sdist, import metadata, and repository
metadata stay aligned.
pixi install
pixi run help
pixi run version-show
pixi run check
pixi run release-check
pixi run qtools-install
pixi run qspy -c /dev/ttyACM0 -b 115200
pixi run bench-smoke
pixi run bench-full --json-out bench_results.jsonlUseful benchmark-oriented Pixi tasks:
pixi run bench
pixi run bench-full
pixi run bench-smoke
pixi run bench-windows-like
pixi run bench-full-windows-like
pixi run bench-full-no-nodelay
pixi run bench-full-no-latency-tuning
pixi run bench-frame-rate-compare
pixi run bench-frame-rate-matrix --ethernet 192.168.10.194
pixi run perf-summary --jsonl bench_results.jsonl
pixi run perf-summary-frame-ratePixi forwards extra arguments after the task name to the underlying command.
That works well for bench subcommand options already baked into the task, so
pixi run bench-full --json-out bench_results.jsonl --label "lab-a" appends
one JSON result object for that run as expected.
For tasks that wrap arena-interface bench, transport selection is easier via
ARENA_ETH_IP or ARENA_SERIAL_PORT because those are top-level CLI options.
For example:
export ARENA_ETH_IP=192.168.10.194
pixi run bench-full --label linux-default --json-out bench_results.jsonlScript-backed tasks such as bench-socket-matrix and bench-frame-rate-matrix
parse their own command-line options, so passing --ethernet or --serial
after the task name is fine there.
Task notes:
bench-fullruns the full suite plus a streaming phase usingpatterns/pat0004.pat.bench-full-windows-likedisablesTCP_QUICKACKwhile leavingTCP_NODELAYon. This is a useful approximation when comparing a Linux host with a Windows-like Ethernet socket policy.bench-full-no-nodelayisolates the effect of disablingTCP_NODELAYwhile leavingTCP_QUICKACKenabled.bench-full-no-latency-tuningdisables bothTCP_NODELAYandTCP_QUICKACK.bench-frame-rate-compareruns four stream-enabled variants back-to-back and appends labeled results tobench_artifacts/frame_rate_results.jsonl.bench-frame-rate-matrixruns the same comparison through the dedicated matrix helper and prints a delta summary relative to the default socket policy.perf-summary-frame-raterenders a compact host-side comparison from the collected frame-rate JSONL file and writesbench_artifacts/frame_rate_summary.json.
python -m pip install -e ".[dev]"
python -m pytest -q
python -m build
python -m twine check dist/*Use the Pixi helper to update the repository version consistently before a release:
pixi run version-show
pixi run version-bump 7.0.1
pixi installversion-bump updates the package metadata files and turns the current
## Unreleased changelog section into a dated release entry. Run pixi install
immediately afterward so pixi.lock is regenerated from the updated metadata
before you commit or tag the release.
bench_results.jsonl stores the host-side benchmark results, while QSPY
captures the raw firmware QS stream so you can compare those host-side
measurements with device-side PERF_* records such as PERF_UPD kind=SPF and
PERF_NET.
A few key metrics are usually enough to compare runs:
- command RTT mean and p99 (
command_rtt) - SPF achieved rate and p99 update RTT (
spf_updates) - stream frame rate and transmit throughput (
stream_frames) - reconnect count plus cleanup status
For a repeatable “how much are the Linux socket optimizations helping?” pass, set the transport once and run the dedicated comparison task:
export ARENA_ETH_IP=192.168.10.194
pixi run bench-frame-rate-compare
pixi run perf-summary-frame-rateThis captures four labeled runs in bench_artifacts/frame_rate_results.jsonl:
linux-defaultwindows-likeno-nodelayno-latency-tuning
The summary reports the deltas relative to linux-default, including stream
rate, stream throughput, SPF achieved rate, and command RTT. Parent directories
for --json-out are created automatically, so bench_artifacts/ does not need
to exist ahead of time.
If you prefer a one-command matrix that also prints a relative delta summary to stdout, use the script-backed task instead:
pixi run bench-frame-rate-matrix --ethernet 192.168.10.194
pixi run perf-summary-frame-rate-matrixmkdir -p bench_artifacts/2026-03-13-eth
pixi run qtools-install
pixi run qspy -c /dev/ttyACM0 -b 115200 2>&1 | tee bench_artifacts/2026-03-13-eth/qspy.logPowerShell:
New-Item -ItemType Directory -Force bench_artifacts\2026-03-13-eth | Out-Null
pixi run qtools-install
pixi run qspy -c COM3 -b 115200 2>&1 | Tee-Object -FilePath bench_artifacts\2026-03-13-eth\qspy.logLeave QSPY running while the benchmark executes in a second terminal. Stop it after the benchmark completes so the log contains the full run.
Set the transport once, then run whichever socket-policy variants you want to compare:
export ARENA_ETH_IP=192.168.10.194
pixi run bench-full --label linux-default --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
pixi run bench-full-windows-like --label windows-like --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
pixi run bench-full-no-nodelay --label no-nodelay --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
pixi run bench-full-no-latency-tuning --label no-latency-tuning --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonlPowerShell:
$env:ARENA_ETH_IP = "192.168.10.194"
pixi run bench-full --label "linux-default" --json-out bench_artifacts\2026-03-13-eth\bench_results.jsonl
pixi run bench-full-windows-like --label "windows-like" --json-out bench_artifacts\2026-03-13-eth\bench_results.jsonlFor a one-command socket comparison matrix with custom output paths, use:
pixi run bench-socket-matrix --ethernet 192.168.10.194 \
--stream-path patterns/pat0004.pat \
--json-out bench_artifacts/2026-03-13-eth/bench_results.jsonlAfter the run, keep at least:
bench_results.jsonlfor host-side timings and metadataqspy.logfor the raw QS stream- a filtered
qspy_perf.logfor quick comparison (optional)
On POSIX you can extract just the performance lines with:
grep 'PERF_' bench_artifacts/2026-03-13-eth/qspy.log > bench_artifacts/2026-03-13-eth/qspy_perf.logPowerShell:
Select-String -Path bench_artifacts\2026-03-13-eth\qspy.log -Pattern 'PERF_' | ForEach-Object { $_.Line } | Set-Content bench_artifacts\2026-03-13-eth\qspy_perf.logGenerate a compact text summary and optionally save a machine-readable JSON summary:
pixi run perf-summary --jsonl bench_artifacts/2026-03-13-eth/bench_results.jsonl \
--qspy-log bench_artifacts/2026-03-13-eth/qspy.log \
--baseline linux-default \
--json-out bench_artifacts/2026-03-13-eth/perf_summary.jsonThe summary tool groups host-side runs by label and reports the latest QSPY
PERF_* records so you can answer questions like: how much slower is the
Windows-like socket policy than the Linux default, did SPF hold 200 Hz, and did
streaming throughput change.
Post-run ALL_OFF cleanup is intentionally treated as a warning when the
measurement phase has already completed. If the host reports
status=ok_cleanup_failed, the measured host-side statistics are still valid
and are preserved in the JSONL output. In that case:
- keep the QSPY log running and save it
- review the saved cleanup diagnostics (
ip route get ...andip neigh show ...on Linux) - compare whether QSPY shows a fresh boot/link sequence or just a host/network path hiccup
For reproducible comparisons, keep the artifact directory together with the firmware commit or tag, host computer, transport, switch/LAN notes, and the benchmark label you used.
The repository includes GitHub Actions workflows for CI and PyPI Trusted Publishing.
Recommended release flow:
- Add release notes under
## UnreleasedinCHANGELOG.md. - Run
pixi run version-bump <version>and thenpixi install. - Run
pixi run release-checkor the equivalent pip commands above. - Commit the release changes and create a release tag such as
<version>orv<version>. - Push the tag to GitHub.
- The
publish.ymlworkflow builds the wheel and sdist, then publishes them to PyPI using Trusted Publishing.
For conda-forge guidance, see RELEASING.md.