Skip to main content

DPEA_DPi

Python drivers for the DPEA Pi family of circuit boards developed by Stan Reifel.

Installation

Add the package to an exhibit project:

uv add dpeaDPi

On the DPEA Raspberry Pi image, this also installs rpi-lgpio, which provides the RPi.GPIO module used by DPiComputer. The image includes the native build dependencies required by lgpio on Python 3.13.

RS485 drivers do not open /dev/serial0 when they are imported or constructed. The default shared network opens it when the first command is sent. Tests and applications can pass a configured DPiNetwork or another compatible network object into a board constructor. The package does not automatically select a simulated hardware backend.

DPiNetwork.sendCommand() returns (True, failed_count) on success and raises DPiCommunicationError for exhausted retries or serial failures. Its pop*() methods raise the same exception for insufficient response data. Injected network implementations must follow this exception contract. Network errors include the available address, command, and retry count. The traceback identifies the caller.

DPiComputer also initializes GPIO and I2C on first use. Its constructor accepts compatible gpio and i2cBus objects for integration tests.

Input validation

Driver methods accept ordinary Python values, with type hints for editor checks and runtime validation before hardware I/O or simulated state changes. Invalid arguments raise ValueError, including Pydantic's ValidationError.

Testing without hardware

There are three separate layers for running without physical boards. Pick the one that matches what you are doing.

  1. Low-level injection (for this package's own tests). Every driver accepts an injected transport or backend: DPiNetwork(serialPort=...) for the RS485 boards, and DPiComputer(gpio=..., i2cBus=...) for GPIO and I2C. This exercises packet and pin behavior. Consumers should not need to emulate packets or pins.

  2. Board simulation (for consumer applications and tests). The dpeaDPi.simulation package provides a SimulatedDPiXxx for each board with the same public methods as the real driver, so application code runs unchanged against either. Simulated physical input (button presses, sensor changes) is driven through a separate .controls object. The simulators use no serial, GPIO, I2C, real sleeps, or threads, and one injected SimClock gives deterministic timing. Stepper moves replay the board firmware's acceleration ramp against that clock, so a move takes the time it would on the board. Time passes only through the clock: state.clock.advance(seconds), or state.run_until_idle() to advance to the end of every pending stepper move. Waiting driver calls advance it the same way.

    from dpeaDPi import DPiCommunicationError
    from dpeaDPi.simulation import SimState, SimulatedDPiButton
    
    state = SimState()
    button = SimulatedDPiButton(state=state)
    button.controls.press(0)
    assert button.readRGBButtonLatch(0) is True
    
    state.fail_next("button", "readRGBButtonLatch")
    try:
        button.readRGBButtonLatch(0)
    except DPiCommunicationError as error:
        assert error.operation == "readRGBButtonLatch"
    

    Import the simulators explicitly. Nothing is auto-selected based on the operating system, and the real drivers never import this package.

  3. Consumer composition (for structuring an exhibit). Choose real or simulated hardware once, at the application's composition root, and keep the decision out of business logic.

The scripts in DPi_Examples run against real hardware only.

Development

Install the locked project and development dependencies:

uv sync --locked --all-groups

Run the tests and build both package distributions:

uv run --locked pytest
uv run --locked pyrefly check
uv build --no-sources

Pyrefly runs in strict mode over the library and examples and gates CI. Test fixture parameters and lambdas may remain inferred, while their bodies and real/simulator protocol assignments in tests/typecheck_protocols.py are still checked.

Behavioral test suite

The tests have both fixed cases and hypothesis generated test cases (property based testing). The fixed cases test the addresses, commands, field order, byte encoding, decoded values, and GPIO pin mappings.
The generated cases then test useful input domains and short state or recovery sequences without replacing those independent tests.

These tests require no physical boards. RS485 driver tests run real DPiNetwork framing and parsing against a scripted serial port. Cases specify expected payload and response bytes, so equivalent uses of the integer push and pop helpers remain interchangeable. DPiComputer tests inject GPIO, PWM, and strict integer-byte I2C backends. Controlled clocks and patched sleeps keep retry and multi-board tests deterministic.

Covered behavior includes:

  • Board addresses, command routing, payload fields, signed values, and response decoding.
  • Transport retries, partial responses, checksum rejection, parser recovery, and transaction isolation.
  • GPIO mapping, PWM lifecycle and channel isolation, Pico I2C values, and pixel upload order.
  • Stepper and Robot configuration, homing, movement, buffering, failure exits, and later recovery.

Run the complete suite or only the generated cases:

uv run --locked pytest -q
uv run --locked pytest -q tests -k generated

The suite has no public method inventory, count assertion, or registration tests. When extending a driver, add expected inputs, wire or GPIO outputs, decoded results, and relevant failure cases to a suitable existing fixture or a focused direct or flow test. A WireCase row is useful for a single-command RS485 path, but it is optional. Multi-command operations need behavioral tests that check required ordering and failure outcomes. Homing tests allow independent motor polls to vary while requiring stops before reversals and cleanup on abort.

Test observable contracts instead of private object layout or unnecessary ordering between independent operations. Preserve required ordering on the same channel, such as stopping PWM before a digital write. New public behavior still needs meaningful tests even though no registry detects it automatically.

Use fixed cases for command numbers, pin mappings, and literal packet anchors. Use generated cases for value boundaries, interleaved state transitions, and failure recovery. A later successful read or motion operation checks recovery beyond a successful ping.

Releases

Confirm representative board behavior on physical hardware before releasing v2. Packet and simulation tests do not establish electrical or motion behavior.

Merging a new package version into main runs the full test and package checks. CI creates a tag such as v1.0.0 from the version in pyproject.toml, then publishes the exact artifacts to PyPI with Trusted Publishing. No manual tag or PyPI upload is required.

Configure the PyPI trusted publisher once with these values:

  • Owner: dpengineering
  • Repository: DPEA_DPi
  • Workflow: publish.yml
  • Environment: pypi

No PyPI token is stored in GitHub.

Metadata

Release files for dpeaDPi 3.0.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 dpeaDPi 3.0.0
File Size Uploaded Provenance
dpeadpi-3.0.0.tar.gz 59.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dpeaDPi 3.0.0
File Interpreter ABI Platform
dpeadpi-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 141.0 kB

Release files / dpeadpi-3.0.0.tar.gz

Download URL dpeadpi-3.0.0.tar.gz
Size 59.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5c2fc6e7cc2ce9bf511ed94cdb6faa3f160e97fb1cb65cdbd3f4f4d9f02961bb
BLAKE2b-256 checksum
How to use checksums
3093e1657eae7c70a99297583add61ce664e915b6ccec88eed62900082e3b83f
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 24, 2026.

Transparency log

Release files / dpeadpi-3.0.0-py3-none-any.whl

Download URL dpeadpi-3.0.0-py3-none-any.whl
Size 81.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4ba8b7d112200d581a49d29640ff82fcd7d0658cbb9348ff403f9f6bfb03c840
BLAKE2b-256 checksum
How to use checksums
06f641ad40e64967a795a4427760915429f9cb73ab6eb9ce5ee7355bc43a07ff
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 24, 2026.

Transparency log

Security for dpeaDPi 3.0.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for dpeadpi-3.0.0.tar.gz

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 24, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files Full provenance

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