Skip to content
Merged
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/contributor_guide/device-driver-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Keep it small and idiomatic to PyLabRobot.
- **Stay OS-agnostic:** no OS-specific libraries or DLLs. Running on Windows, Mac, and Linux is what keeps experiments portable and reproducible.
- **Use `pylabrobot.io` for all device communication.** Use the appropriate PyLabRobot transport (`USB`, `Serial`, `FTDI`, `HID`, `Socket`, etc.) instead of calling PyUSB, pyserial, hidapi, raw sockets, vendor DLLs, or OS APIs directly from a device driver. If a required transport capability is missing, add it to `pylabrobot.io` rather than bypassing the abstraction.
- **Async `setup()` / `stop()`** plus public operation methods over those `pylabrobot.io` transport primitives.
- **Leave the device in the state you found it at each lifecycle boundary.** Restore changes made for a `setup()` / `stop()` lifecycle in `stop()`, and restore per-command changes before the command finishes. If the driver needs to modify device memory, registers, or configuration, read and save the original values first and restore those exact values at the end of the relevant scope, not assumed defaults. Ensure cleanup also runs on errors and cancellation, including partial setup failures.
- **Log important device events.** Define a module logger with `logger = logging.getLogger(__name__)` and use it for meaningful lifecycle events, operations, state changes, recoveries, and faults. Use the appropriate log level and structured `%`-style arguments; don't use `print()` for runtime status.
- **Prefer string `Literal[...]` over enums**, especially anything user-facing. A `Literal["standard", "head", "pump"]` argument plus an internal dict mapping to wire codes reads better at the call site than an enum import. `IntEnum` is fine in narrow internal cases (e.g. a fixed set of wire/register codes never exposed to callers).
- **API docs:** add `docs/api/pylabrobot.<vendor>.rst` plus a line in `docs/api/pylabrobot.rst`.
Expand Down
Loading