Skip to main content

nxs

Python SDK and command-line tool for NXS sensor co-processors. The library covers personality authoring (a click personality is a Python class compiled to VM bytecode) and integration (open_client(), decoded sample streams, parameter access). The nxs CLI is built on the same public imports: personality compile and upload, VM control, sample streaming, personality store management, and firmware update over I2C, serial, or CAN.

from nxs import open_client

client = open_client("i2c", bus="/dev/i2c-2", address=0x30)
for sample in client.iter_samples():
    handle(sample.values)

Contracts and agents

Every YAML the tool reads ships with a JSON Schema under nxs/schemas/. Among them are the suite manifest, the click and cam personality facts files, the hub manifests and the topology files. Editors enforce the schemas through the files' yaml-language-server modelines, and CI enforces them on the shipped personalities and hubs. nxs status validates the suite manifest against its schema before the laws run. The hub, facts, blob and topology loaders parse strictly, so an unknown key or a malformed value is an error naming the file.

Every read verb also emits its document as JSON (nxs status --json, nxs cam1 status --json, nxs cam1 caps --json), each conforming to the shipped surface contract. Shape is the schema's job. The timing and feasibility laws stay in code and answer through nxs status: a refusal is one fact line, then the lawful alternatives under it.

nxs mcp serves the same verbs to an AI agent over the Model Context Protocol (install the mcp extra). Hand-written YAML, the nxs tune personality panel, and the MCP tools edit one declared config through the same laws; MCP also operates the hardware, and a refused request carries its refusal. See the MCP Tool Reference in the released documentation set.

Install

Requires Python ≥ 3.10. The base install covers every wire, I2C, Cyphal/serial and Cyphal/CAN, through the bundled library; the cyphal extra adds pyserial for the serial port autodetect. The Cyphal DSDL ships vendored in the wheel for yakut and yukon, so they need no repo checkout and no public_regulated_data_types clone.

uv, native with direct device access; the only option on macOS, where Docker cannot reach USB:

uv tool install 'aliensense-nxs[cyphal]'      # omit [cyphal] for an I2C-only install

pip, from a release wheel:

python3 -m pip install 'aliensense_nxs-<version>-py3-none-manylinux_2_35_x86_64.whl[cyphal]'

Container, for fleet, hermetic, or locked-down hosts; ships no ROS. See Dockerfile:

docker build --build-arg EXTRA='[cyphal]' -t nxs:cyphal .
docker run --rm --device /dev/ttyUSB0 nxs:cyphal --transport cyphal-serial \
    --port /dev/ttyUSB0 --format json

nxs switch installs the platform's udev bus aliases and the tab completion at /etc/bash_completion.d/nxs (the writes under /etc go through sudo); zsh sources the same file after autoload -U compinit && compinit.

Deploy to a Jetson

From a dev host to the target. The target keeps exactly one nxs, the installed wheel. Never copy the source tree to the target and never pip install -e there: a second copy shadows the wheel and personality edits stop reaching the compiler.

1. Build the wheel (dev host, in this directory):

python3 -m pip install build
python3 -m build --wheel

The wheel lands in dist/. A standalone checkout carries the vendored DSDL and builds as-is; in a source checkout, run ../scripts/vendor-dsdl.sh first so the bundle is current.

2. Copy to the Jetson and install:

scp dist/aliensense_nxs-<version>-py3-none-manylinux_2_35_aarch64.whl <user>@<jetson>:/tmp/
ssh <user>@<jetson> "python3 -m pip install --user --force-reinstall 'aliensense-nxs[cyphal] @ file:///tmp/aliensense_nxs-<version>-py3-none-manylinux_2_35_aarch64.whl'"

--force-reinstall because dev wheels reuse the version number. The PEP 508 name[extra] @ file:// form is required; pip does not apply extras to a bare wheel path. For an I2C-only target install the bare path with no extras: pip install --user --force-reinstall /tmp/aliensense_nxs-<version>-py3-none-manylinux_2_35_aarch64.whl.

3. Verify the single installed copy:

ssh <user>@<jetson> "nxs --version && python3 -c 'import nxs, os; print(os.path.dirname(nxs.__file__))'"

The printed path must be under ~/.local/lib/python3.*/site-packages. Any other path (a home-directory source tree, an editable install) is a shadowing copy: python3 -m pip uninstall nxs until none remains, then reinstall the wheel.

Iterating on a personality needs no redeploy. Compile on the dev host, ship the image:

nxs upload fxos8700 --config bus=spi -o fxos8700.nxs    # dev host: compile only
scp fxos8700.nxs <user>@<jetson>:
ssh <user>@<jetson> nxs upload fxos8700.nxs

An image whose format predates the installed tool is refused together with its rebuild command.

Then bring the sensor up with the Quick start commands below (probe, upload iam20680 --param sample_rate=250, stream, store save 0).

Quick start

nxs probe
nxs upload iam20680 --param sample_rate=250
nxs stream
nxs store save 0
nxs push-fw zephyr.signed.bin

The default transport is I2C on a Linux host (Jetson/SBC) and cyphal-serial on macOS or Windows, which have no /dev/i2c-*. $NXS_TRANSPORT overrides the choice (i2c / cyphal-serial / cyphal-can); $NXS_BUS sets the I²C bus and $NXS_PORT the serial port or SocketCAN interface, or pass -t, -b, -p per command. nxs --help lists every command.

ROS 2

nxs ros2 maps the device-served field descriptors onto standard ROS 2 messages by semantic, with no per-sensor configuration. With a suite manifest it bridges every unit under nxs/<unit>/...; with --unit or explicit transport flags it bridges one device. Install the wheel with the ros2 extra (aliensense-nxs[cyphal,ros2]) into a sourced ROS 2 environment (rclpy comes from the distribution; only this verb imports it) and run:

nxs ros2 --plan     # print the topic plan, no ROS required
nxs ros2            # publish; ros2 topic echo nxs/<unit>/imu

The topic table, timestamp and covariance conventions are in the integration manual's ROS 2 section.

Cameras (nxs cam)

nxs cam brings up and drives camera chains, an image sensor behind a serializer behind a deserializer link. Two kinds of node describe the hardware, both found at run time. A hub carries the deserializer's and the serializer's facts, the flows that compose a port and the default wiring. A cam personality carries one sensor's facts, its program and its register tables, and every link offers every installed one. The tool is hardware-agnostic, and the hub and the cam personality are the camera's self-description.

Commands address the hardware node first, the port and then optionally one link:

nxs cam0 status              # presence of every device on every link, then the readbacks
nxs cam0 caps                # modes and knobs: feature discovery
nxs cam0 on                  # bring the port's links up (constructs as needed)
nxs cam0 A set exposure 4ms  # a knob on one link, judged by the laws; a refused
                             # value names the lawful alternatives
nxs cam0 capture --frames 60  # delivery at the declared rate, headless
nxs cam0 off

cam0 is the connector's stable name, since nxs switch installs the platform's udev aliases, and A and B are its links. The ports come from the suite manifest's ports: section: which hub on which bus, which chains behind it, the declared mode and sync. A host without a manifest follows the booted device tree and the hub's default topology, and nxs tune --freeze --ports writes what it found.

The hub ships inside the wheel. The cam personalities ship as sealed images in the release assets, and nxs personality install <directory> installs one from its source. A development host names its own trees with $NXS_CAM_HUBS and $NXS_CAM_PERSONALITIES under nxs --experimental. Without a hub for the declared deserializer, or a cam personality for the declared sensor, the tool says so and where it searched. Authoring a cam personality is the Cam Personality Reference (docs/nxs-cam-personalities.md in a standalone checkout), shipped with the product documentation. The guide set on the documentation site (https://aliensense.github.io/nxs-docs/guides/) walks from a fresh Jetson to a dual camera.

Reference

The full interface contract (register map, procedures, framing, limits) is the NXS host interface specification, shipped with the product documentation.

Building from source

The Cyphal DSDL is vendored into the wheel but not committed. It is assembled from the firmware's dsdl/aliensense types and the full uavcan namespace of OpenCyphal's public_regulated_data_types, which yakut and yukon need beside the vendor types (uavcan.node, uavcan.file, and their dependencies).

A standalone checkout carries the bundle in nxs/dsdl/ already, assembled by the release pipeline before building the wheel. Run that step by hand before building the cyphal container or running the cyphal tests from a fresh source checkout:

../scripts/vendor-dsdl.sh        # needs `west update`, or PRDT=/path

Metadata

Release files for aliensense-nxs 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for aliensense-nxs 1.2.0
File Interpreter ABI Platform
aliensense_nxs-1.2.0-py3-none-manylinux_2_35_x86_64.whl Python 3 none Linux glibc 2.35+ x86-64 Details
aliensense_nxs-1.2.0-py3-none-manylinux_2_35_aarch64.whl Python 3 none Linux glibc 2.35+ ARM64 Details
aliensense_nxs-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 5.0 MB

Release files / aliensense_nxs-1.2.0-py3-none-manylinux_2_35_x86_64.whl

Download URL aliensense_nxs-1.2.0-py3-none-manylinux_2_35_x86_64.whl
Size 1.9 MB
Tags Linux glibc 2.35+ x86-64 Python 3
SHA-256 checksum
How to use checksums
796701d66e152796fe189ee8f328ba9b16bce87a73f73107eaac59e16202573a
BLAKE2b-256 checksum
How to use checksums
c36d4185215e8576841040263cfcc62ddfae389124179378412e1aae59ca1963
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / aliensense_nxs-1.2.0-py3-none-manylinux_2_35_aarch64.whl

Download URL aliensense_nxs-1.2.0-py3-none-manylinux_2_35_aarch64.whl
Size 2.0 MB
Tags Linux glibc 2.35+ ARM64 Python 3
SHA-256 checksum
How to use checksums
86602ec66c840f3318692013e8668cc4b99bcadfb713e98744dfd95a2cbab480
BLAKE2b-256 checksum
How to use checksums
29b4d0a1cb4a994f99448549916d357bb2d54067d7d083dbc6a84cd486e933ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / aliensense_nxs-1.2.0-py3-none-any.whl

Download URL aliensense_nxs-1.2.0-py3-none-any.whl
Size 1.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
bf7e2a62ccfe03c9a902a0ba455475ab4bb957e2127b60032aa1c8eef6614d09
BLAKE2b-256 checksum
How to use checksums
ab899aaa8ca1fb79f42c56845ceaa7a405b8fea179e6716240d9806c4dac4cd0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Security for aliensense-nxs 1.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page