Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8a460c4
update CONTRIBUTING.md
raiden00pl Feb 7, 2026
a30c8bd
fix some qa issues
raiden00pl Mar 11, 2026
fc0bd6c
add support for UDP transport
raiden00pl Mar 13, 2026
7074644
update doc with dummy dev commands
raiden00pl Mar 14, 2026
239a2f6
enable bitrate support for interfaces
raiden00pl Mar 11, 2026
b0f08be
support for dynamic plugins management
raiden00pl Mar 11, 2026
37a6b70
expose more interfaces from nxslib
raiden00pl Mar 11, 2026
4087f04
improve devinfo tests
raiden00pl Mar 11, 2026
f82e4f5
fix queue deinit
raiden00pl Mar 11, 2026
771b796
refactor channel handling to ChannelRef
raiden00pl Mar 13, 2026
b9b5802
add provider stream routing support
raiden00pl Mar 13, 2026
8465b5e
doc update about lib usage
raiden00pl Mar 12, 2026
858feb0
use context manager to handle objects cleanup
raiden00pl Mar 13, 2026
b5a5278
use fake nxscope for tests
raiden00pl Mar 13, 2026
6b7a31d
use numpy data stream
raiden00pl Mar 13, 2026
716558f
add virtual channel runtime and vadd command
raiden00pl Mar 14, 2026
d0b67c8
add shared sample and window transform modules
raiden00pl Mar 14, 2026
48f155e
transforms: add shared stream pipeline for processor fan-out
raiden00pl Mar 14, 2026
f6cd975
stream: add shared physical fan-out hub for multi-plugin data reuse
raiden00pl Mar 14, 2026
51cd84b
add support for control server
raiden00pl Mar 15, 2026
375f4f1
move nxscli-np plugin to nxscli
raiden00pl Mar 16, 2026
e93715e
update dummy dev channels
raiden00pl Mar 16, 2026
8d6f6e5
add more dummy test channels
raiden00pl Mar 16, 2026
98981f6
add plot handler and plugin isntance interfaces
raiden00pl Mar 16, 2026
5c9edd9
use AckMode for ack mode
raiden00pl Mar 18, 2026
014fe0b
fix typos
raiden00pl Mar 18, 2026
9757f1a
control server works only on unix
raiden00pl Mar 18, 2026
e09942e
release 1.0.0
raiden00pl Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@

- add support for UDP data stream (only json for now)
- add support for RTT interface

## 1.0.0 (18/03/2026)

- support for nxslib 1.0.0
- move nxscli-np plugin to nxscli
- support for dynamic plugins management
- add provider stream routing support
- add support for control server
- add shared sample and window transform modules
- add virtual channel runtime and vadd command
42 changes: 39 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

### Recommended tools

We use [tox](https://github.com/tox-dev/tox) to automate tedious developer's tasks,
We use [tox](https://github.com/tox-dev/tox) to automate tedious developer's tasks,
thus installing it is highly recommended.

```
Expand Down Expand Up @@ -31,7 +31,43 @@ source venv/bin/activate

### Code style and running tests

Code formatting is ensured by [black](https://github.com/psf/black) and [isort](https://github.com/PyCQA/isort).
#### Docstring Format

This project uses Sphinx-style docstrings exclusively.
Do not use Google-style or NumPy-style docstrings.

Correct (Sphinx style):
```python
def example_function(param1, param2):
"""Brief description of function.

Longer description if needed.

:param param1: description of param1
:param param2: description of param2
:return: description of return value
:raises ValueError: description of when this is raised
"""
```

Incorrect (Google style) - DO NOT USE:
```python
def example_function(param1, param2):
"""Brief description of function.

Args:
param1: description of param1
param2: description of param2

Returns:
description of return value
"""
```

#### Code Formatting

Code formatting is ensured by [black](https://github.com/psf/black)
and [isort](https://github.com/PyCQA/isort).
To reformat your changes, use:

```
Expand All @@ -51,7 +87,7 @@ Flake8 linter is available with:
tox -e flake8
```

CI requres 100% coverage to pass. If some of your changes can't be easy tested,
CI requires 100% coverage to pass. If some of your changes can't be easy tested,
you can exclude code from coverage with `#pragma: no cover` comment.
To run tests with coverage report run:

Expand Down
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,49 @@
Nxscli is a command-line client package for the [Apache NuttX](https://nuttx.apache.org/)
NxScope real-time logging module.

It is also a reusable Python runtime layer for NxScope streaming, channel
control, triggers, and plugin orchestration. The `nxscli` internals are used
by other tools (for example GUI applications) to build more advanced workflows
without re-implementing NxScope communication logic.

Compatible with Python 3.10+.

## Features

* Plugins architecture, extendable through ``nxscli.extensions`` entrypoint
* Client-based triggering (global and per-channel triggers)
* Save data to CSV files
* Save data to Numpy files (`pnpsave`) and memmap files (`pnpmem`)
* Print samples
* Stream data over UDP (compatible with [PlotJuggler](https://github.com/facontidavide/PlotJuggler))
* NxScope protocol via serial port or Segger RTT interface
* Virtual channels and math operations on channels data
* Optional control server (`--control-server`) for extensions

## Features Planned

* More triggering types
* Boolean operations on triggers
* Virtual channels and math operations on channels data
* Improve `pdevinfo` output (human-readable prints)
* Interactive mode

## Plugins

By default, we only support features that depend on the standard Python libraries.
The functionality is expadned by installing plugins.
Plugins are automatically deteceted by Nxscli.
By default, `nxscli` ships with core plugins including CSV, printer, UDP,
and NumPy file capture (`pnpsave` and `pnpmem`).
Additional functionality is expanded by installing optional plugins.
Plugins are automatically detected by Nxscli.

Available plugins:

* [nxscli-mpl](https://github.com/railab/nxscli-mpl) - Matplotlib extension
* [nxscli-np](https://github.com/railab/nxscli-np) - Numpy extension

## Plugins Planned

* Stream data as audio (inspired by audio knock detection systems)
* PyQtGraph support

## Instalation
## Installation

Nxscli can be installed by running `pip install nxscli`.

Expand All @@ -51,10 +58,22 @@ To install latest development version, use:

Look at [docs/usage](docs/usage.rst).

## Reuse as a Library

`nxscli` is not only a CLI frontend. It can be imported and reused by external
applications that need:

* NxScope connection handling (serial/RTT and compatible interfaces)
* channel configuration and stream lifecycle control
* plugin loading and runtime execution
* trigger and data-processing orchestration

This makes `nxscli` the integration layer for higher-level tools such as
custom dashboards, GUIs, and automation scripts.


## Contributing

All contributions are welcome to this project.

To get started with developing Nxscli, see [CONTRIBUTING.md](CONTRIBUTING.md).

44 changes: 44 additions & 0 deletions docs/library.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Using Nxscli as a Library
-------------------------

Nxscli is not only a CLI frontend. It can also be reused as a Python
integration layer for higher-level tools such as GUIs, dashboards, and
automation scripts.

Typical reusable components include:

* NxScope connection and interface handling
* channel configuration and stream lifecycle control
* plugin loading and runtime orchestration
* trigger and data-processing integration

Minimal example
===============

.. code-block:: python

from nxscli.plugins_loader import plugins_list
from nxscli.phandler import PluginHandler
from nxslib.intf.dummy import DummyDev
from nxslib.proto.parse import Parser
from nxslib.nxscope import NxscopeHandler

intf = DummyDev()
parse = Parser()

with NxscopeHandler(intf, parse) as nxscope:
with PluginHandler(plugins_list) as phandler:
phandler.nxscope_connect(nxscope)

# Configure and run as needed by your application:
nxscope.ch_enable([0], writenow=True)
nxscope.stream_start()
pid = phandler.plugin_start_dynamic("pprinter", channels=[0])

# ... do work ...

phandler.plugin_stop_dynamic(pid)
nxscope.stream_stop()
# phandler.cleanup() called automatically on exit
# nxscope.disconnect() called automatically on exit

140 changes: 122 additions & 18 deletions docs/usage.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
=====
Usage
-----
=====

Commands
---------
========

You can run Nxscli as a Python module:

Expand All @@ -24,40 +25,61 @@ the same time.

For commands details use ``--help`` option.

Global options include:

* ``--control-server`` - enable optional control server plugin
(disabled by default).
* ``--control-endpoint`` - server endpoint
(``unix://``, ``unix-abstract://`` or ``tcp://``).

The following example illustrates how to run multiple plugins simultaneously
with various channel configurations (based on ``pcap`` from ``nxscli-mpl``):

.. code-block:: bash

python -m nxscli dummy chan 1,2,3,4 pcap --chan 1 100 pcap --chan 2,3 200 pcap 300

Library integration guide:

* :doc:`library`

Interace commands
=================
Interface Commands
------------------

Supported interface commands:

* ``dummy`` - select simulated NxScope interface

Available device channels:

- chan0 - vdim = 1, random()
- chan1 - vdim = 1, saw wave
- chan2 - vdim = 1, triangle wave
- chan3 - vdim = 2, random()
- chan4 - vdim = 3, random()
- chan5 - vdim = 3, static vector = [1.0, 0.0, -1.0]
- chan6 - vdim = 1, 'hello' string
- chan7 - vdim = 3, static vector = [1.0, 0.0, -1.0], meta = 1B int
- chan8 - vdim = 0, meta = 'hello string', mlen = 16
- chan9 - vdim = 3, 3-phase sine wave
- 0: noise_uniform_scalar - vdim = 1, random()
- 1: ramp_saw_up - vdim = 1, saw wave
- 2: ramp_triangle - vdim = 1, triangle wave
- 3: noise_uniform_vec2 - vdim = 2, random()
- 4: noise_uniform_vec3 - vdim = 3, random()
- 5: static_vec3 - vdim = 3, static vector = [1.0, 0.0, -1.0]
- 6: text_hello_sparse - vdim = 1, sparse 'hello' string
- 7: static_vec3_meta_counter - vdim = 3, static vec + 1B meta counter
- 8: meta_hello_only - vdim = 0, mlen = 16, meta = 'hello string'
- 9: sine_three_phase - vdim = 3, 3-phase sine wave
- 10: reserved (undefined)
- 11: fft_multitone - vdim = 1, deterministic multi-tone
- 12: fft_chirp - vdim = 1, deterministic chirp-like signal
- 13: hist_gaussian - vdim = 1, deterministic Gaussian-like
- 14: hist_bimodal - vdim = 1, deterministic bi-modal
- 15: xy_lissajous - vdim = 2, correlated XY signal
- 16: polar_theta_radius - vdim = 2, (theta, radius) signal
- 17: step_up_once - vdim = 1, one rising step
- 18: step_down_once - vdim = 1, one falling step
- 19: pulse_square_20p - vdim = 1, periodic square pulse (20% duty)
- 20: pulse_single_sparse - vdim = 1, one-sample pulse every 250 samples

* ``serial`` - select serial port NxScope interface

* ``rtt`` - select Segger RTT as NxScope interface

Configuratio commands
=====================
Configuration Commands
----------------------

Available configuration commands:

Expand All @@ -74,16 +96,98 @@ Available configuration commands:

Triggers can be configured per channel with the option ``--trig``.

* ``vadd`` - add virtual channel in `nxscli` virtual runtime.

This command declares a derived channel from one or more inputs.
The command is non-interactive and can be chained with plugin commands.
Use ``--operator`` to select transform and ``--params`` for
comma-separated ``key=value`` operator arguments.

Example command form:

.. code-block:: bash

Plugin commands
===============
python -m nxscli dummy vadd --operator scale_offset --params scale=2,offset=1 100 0 pprinter --chan v100 10

In command chaining, place command options before positional arguments.
For virtual data output, select virtual channel explicitly via plugin
``--chan vNN`` (for example ``--chan v100``).
Source physical channels from ``vadd`` inputs are auto-configured.


Plugin Commands
---------------

Plugins supported so far:

* ``pcsv`` - store samples in CSV files
* ``pnpsave`` - store samples in Numpy ``.npy`` files
* ``pnpmem`` - store samples in Numpy memmap ``.dat`` files
* ``pdevinfo`` - show information about the connected NxScope device
* ``pnone`` - capture data and do nothing with them
* ``pprinter`` - capture data and print samples
* ``pudp`` - stream data over UDP

For more information, use the plugin's ``--help`` option.

Dummy Device Cheatsheet
=======================

Use these commands for quick local testing without hardware.
All examples use the ``dummy`` interface and channel ``0``.

Device info
===========

.. code-block:: bash

python -m nxscli dummy pdevinfo

Print stream samples
====================

.. code-block:: bash

python -m nxscli dummy chan 0 pprinter 50

Capture and discard samples
===========================

.. code-block:: bash

python -m nxscli dummy chan 0 pnone 50000

Store samples to CSV
====================

.. code-block:: bash

python -m nxscli dummy chan 0 pcsv 200 /tmp/nxscope_csv

Store samples to Numpy files
----------------------------

.. code-block:: bash

python -m nxscli dummy chan 0 pnpsave 200 /tmp/nxscope_np

Store samples to Numpy memmap
-----------------------------

.. code-block:: bash

python -m nxscli dummy chan 0 pnpmem 200 /tmp/nxscope_mem 100

Stream samples over UDP
=======================

.. code-block:: bash

python -m nxscli dummy chan 0 pudp 2000 --address 127.0.0.1 --port 9870

Run multiple plugins in one command
===================================

.. code-block:: bash

python -m nxscli dummy chan 0 pprinter 20 pcsv 20 /tmp/nxscope_csv pudp 20
Loading
Loading