Skip to main content

hilspy

HILS (hardware-in-the-loop simulation) I/O for Python on a Rust core, built to be embedded in a scenario library (such as autoware_carla_scenario).

One call opens a channel: a transport (how packets travel) composed with a codec (what they mean). Both are pluggable, in Rust or in Python.

import hilspy

with hilspy.open("can://vcan0", "dbc:vehicle.dbc") as ecu:
    ecu.send("VehicleSpeed", {"Speed": 12.5, "Accel": 0.0, "Gear": "D", "Counter": 0})
    for msg in ecu:  # until ecu.close()
        print(msg.name, msg.fields)  # "SteeringCmd" {"SteeringAngle": -3.5, ...}
Transport URL
can://vcan0 Linux SocketCAN (?fd, ?echo, ?filter=0x100:0x700,...)
udp://host:port UDP to a peer (?bind=addr:port); udp://addr:port?listen replies to the last sender
tcp://host:port TCP client; tcp://addr:port?listen serves every connected client
mem://name in-process bus (tests, simulated ECUs in one process)
file://path replay a recording; ?write / ?append records one
Codec
raw (default) none: messages carry data (and id for CAN)
dbc:FILE CAN frames <-> DBC messages, via can-dbc (options strict, scaling, decode_choices)
sbf Septentrio Binary Format stream <-> blocks, via libsbf; encodes PVTGeodetic and AttEuler

Install

Python 3.10+. One abi3 wheel per platform serves every Python version; wheels are built for Linux (x86_64, aarch64), macOS (arm64, x86_64) and Windows x64. can:// (SocketCAN) is Linux-only; every other transport and codec works everywhere.

pip install hilspy
uv add hilspy
pip install git+https://github.com/hakuturu583/hilspy   # from source (needs Rust)

From a checkout:

uv sync                             # builds the extension with maturin
uv run pytest

Versions follow semver and are released by labelling the PR (bump patch / bump minor / bump major); see docs/releasing.md.

API

The whole public API:

Name
hilspy.open(url, codec="raw", **codec_options) -> Channel open a channel
Channel.send(message) / send(name, fields) encode and send
Channel.recv(timeout=None) -> Message | None next message (iterate the channel for all)
Channel.every(period, message_or_name, fields=None, *, duration=None) -> Periodic cyclic send from a Rust thread; update(), stop(), period, sent_count
Channel.close() also via with
hilspy.Message(name=None, fields=None, *, data=None, id=None, extended=None, fd=False) .name, .fields, msg["field"], .data, .id, .timestamp
hilspy.register_transport(scheme, factory) / register_codec(name, factory) plugins
hilspy.Error bad URL/codec/option, encode/decode failure, closed channel

A message with a name goes through the codec; a nameless one (Message(data=b"...", id=0x123)) is sent as is. Messages the codec does not know (a CAN id missing from the DBC) arrive nameless.

GNSS receiver simulation (SBF over TCP)

with hilspy.open("tcp://0.0.0.0:28784?listen", "sbf") as receiver:
    receiver.send(
        "PVTGeodetic", {"mode": 4, "latitude": lat_rad, "longitude": lon_rad, "height": 40.0}
    )
    receiver.send("AttEuler", {"heading": 90.0, "pitch": 0.0, "roll": 0.0})
    # tow/wnc default to the current GPS time

Plugins

A transport is any object with send(packet) and recv(timeout) (and optionally close()); a codec has encode(message) and decode(packet). Packets are nameless Messages.

class SerialTransport:
    def __init__(self, address: str, options: dict[str, str]):
        self.port = serial.Serial(address, int(options.get("baud", 115200)))

    def send(self, packet):
        self.port.write(packet.data)

    def recv(self, timeout):
        self.port.timeout = timeout
        data = self.port.read(self.port.in_waiting or 1)
        return hilspy.Message(data=data) if data else None


hilspy.register_transport("serial", SerialTransport)
gnss = hilspy.open("serial:///dev/ttyACM0?baud=921600", "sbf")

Rust crates register through hilspy_core::transport::register and hilspy_core::codec::register.

A virtual CAN interface for local testing:

sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 mtu 72        # CAN FD
sudo ip link set up vcan0

Examples

uv run python examples/virtual_ecu.py                              # cyclic DBC message, in-process
uv run python examples/virtual_ecu.py --url can://vcan0
uv run python examples/gnss_simulator.py "tcp://127.0.0.1:28784?listen"
uv run python examples/gnss_simulator.py "file://sim.sbf?write" --seconds 5
uv run python examples/sbf_dump.py file://sim.sbf

Development

uv sync                                 # build + dev dependencies (cantools for cross-checks)
cargo test -p hilspy-core               # Rust unit tests
uv run pytest                           # Python tests
HILSPY_TEST_VCAN=vcan0 uv run pytest tests/test_socketcan.py   # needs a vcan interface
uv run pre-commit run --all-files       # ruff, mypy, cargo fmt, clippy

Design notes: docs/design.md.

License

Apache-2.0

Metadata

Release files for hilspy 0.3.0

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

Source distribution (sdist)

Source distribution for hilspy 0.3.0
File Size Uploaded
hilspy-0.3.0.tar.gz 61.1 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for hilspy 0.3.0
File
hilspy-0.3.0-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
hilspy-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
hilspy-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
hilspy-0.3.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
hilspy-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 4.2 MB

Release files / hilspy-0.3.0.tar.gz

Download URL hilspy-0.3.0.tar.gz
Size 61.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f083d012de9c7e3284c7e16896ac61a70748fe80c4e08a3becb614dd4bbd2245
BLAKE2b-256 checksum
How to use checksums
6c14171f9c7226256cff54ddeb7f79d61cfb9915265d073fd8e850dccd1f57ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / hilspy-0.3.0-cp310-abi3-win_amd64.whl

Download URL hilspy-0.3.0-cp310-abi3-win_amd64.whl
Size 765.7 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
bc81e7d5dc4915ddc9c7b17b357a3757cb1d768d7615120f2db8bbf146db5c5b
BLAKE2b-256 checksum
How to use checksums
beb090ec17e49ea0a823dc38927e2713cc7d586660e12237b323e3f12762b3ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / hilspy-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL hilspy-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 893.1 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f68802dbc34013b5f4c3bb3b285f1ee0ad4c42de3f71db8c91883cad343ca7cb
BLAKE2b-256 checksum
How to use checksums
4b757e63154412e5475b0db56d058d2aa688b9b17e667ea1f7762640c04a9054
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / hilspy-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL hilspy-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 878.2 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
ca13fe86d37a6617423c8a37f9522a0c461b518dfe973be7f181f8a6e4e4d1cd
BLAKE2b-256 checksum
How to use checksums
ff2ce576341456184ef4f6a40e1cb2851ef54618284a79242c58667e3dbf4d4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / hilspy-0.3.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL hilspy-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Size 805.5 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
3f3ea1444470091d6dff788ee0e6f8267857a9a94f6fd6eeb8b38ec9395b6506
BLAKE2b-256 checksum
How to use checksums
67f79d18a1a5107ebc350c33775f244be9870a9c2188e5a15e1b7963135dbea4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / hilspy-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl

Download URL hilspy-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 826.0 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
9aad8da1e9a57c81ab509a5783c5edd639cf172d7464c965be0ad51f1f842ccb
BLAKE2b-256 checksum
How to use checksums
723a48bf7bb1cbfb606d339bb395ba48ce2db8368e176088448961d2e668e3b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

0.12.0

6 release files

0.11.0

6 release files

0.10.0

6 release files

0.9.0

6 release files

0.8.0

6 release files

0.7.0

6 release files

0.6.0

6 release files

0.5.0

6 release files

0.4.1

6 release files

0.4.0

6 release files

This release

0.3.0 This release

6 release files

0.2.0

6 release files

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