Metadata-Version: 2.4
Name: jumpstarter-driver-obd
Version: 0.8.2.dev211+ga8120be56
Summary: OBD-II vehicle diagnostics driver for Jumpstarter
Project-URL: Homepage, https://jumpstarter.dev
Project-URL: source_archive, https://github.com/jumpstarter-dev/repo/archive/a8120be56ed67f3cfe0797614df168557f87ec71.zip
Author-email: Marek Mahut <marek@mahut.dev>
License-Expression: Apache-2.0
Requires-Python: >=3.11
Requires-Dist: jumpstarter
Requires-Dist: obd>=0.7.1
Description-Content-Type: text/markdown

# OBD-II Driver

`jumpstarter-driver-obd` wraps [python-obd](https://python-obd.readthedocs.io/en/latest/)
to query On-Board Diagnostics (OBD-II) PIDs from a vehicle ECU via an ELM327 adapter.

## Installation

```{code-block} console
:substitutions:
$ pip3 install --extra-index-url {{index_url}} jumpstarter-driver-obd
```

## Hardware Requirements

- An ELM327 USB adapter (e.g. PremiumCord ELM327 USB)
- A vehicle with an OBD-II port (petrol cars from 2001+, diesel from 2004+, all US cars from 1996+)
- **macOS only**: ELM327 USB cables use a CH340 or CP2102 USB-serial chip that may need a kernel
  extension — install the appropriate driver if the port does not appear after plugging in

## Configuration

### Auto-detect (recommended for a single adapter)

Leave `port` unset or `null` to let python-obd scan available serial ports and connect to the first
ELM327 it finds:

```yaml
export:
  obd:
    type: jumpstarter_driver_obd.driver.OBD
    config:
      port: null
```

```{note}
Auto-detect is reliable on Linux (e.g. `/dev/ttyUSB0`). On **macOS** it is not: python-obd
enumerates the `/dev/tty.*` call-in device nodes, but ELM327 adapters only open on the matching
`/dev/cu.*` call-out node, so auto-detect fails to connect. On macOS, pass an explicit
`/dev/cu.usbserial-*` port instead.
```

### Explicit port

Specify the serial port directly when you have multiple adapters or want a deterministic setup:

```yaml
export:
  obd:
    type: jumpstarter_driver_obd.driver.OBD
    config:
      port: /dev/ttyUSB0       # Linux
      # port: /dev/cu.usbserial-XXXX   # macOS
      baudrate: 38400
```

### Config parameters

| Parameter | Description | Type | Required | Default |
|-----------|-------------|------|----------|---------|
| port | Serial port path; `null` to auto-detect an ELM327 adapter | str \| null | no | null |
| baudrate | ELM327 baud rate | int | no | 38400 |
| fast | Enable ELM327 fast mode (~100–400 ms faster per query); unreliable on cheap clone adapters, so it is opt-in | bool | no | false |

## Usage

```python
from jumpstarter_driver_obd import OBDConnectionStatus

# Check connection state
status = obd.status()                              # returns OBDConnectionStatus
print(status == OBDConnectionStatus.CAR_CONNECTED) # True
print(obd.is_connected())                          # True

# Discover what the ECU supports
cmds = obd.supported_commands()   # ["RPM", "SPEED", "COOLANT_TEMP", ...]

# Query individual PIDs by name
rpm   = obd.query("RPM")          # "3000.0 revolutions_per_minute"
speed = obd.query("SPEED")        # "60.0 kph"
temp  = obd.query("COOLANT_TEMP") # "90.0 degC"

# Clearing trouble codes is a separate, explicit call (see note below)
obd.clear_dtc()
```

`query()` returns `None` when the ECU does not answer the command (unsupported PID
or no vehicle on the bus). It is read-only: it refuses destructive commands such as
`CLEAR_DTC` (OBD-II mode 04, which erases stored trouble codes and resets emissions
readiness monitors). To clear codes deliberately, call `clear_dtc()` instead.

## Troubleshooting

**Port not found on macOS**
Run `ls /dev/cu.*` before and after plugging in the cable to spot the new device.
Install a CH340 or CP2102 USB-serial kernel extension if no new port appears.

**Permission denied on Linux**
Add your user to the `dialout` group and log out/in:
```shell
sudo usermod -aG dialout $USER
```
Alternatively, create a udev rule for the adapter's USB vendor/product ID.

**"No OBD-II adapters found"**
Make sure the cable is seated in the OBD-II port (typically under the dashboard on the driver's side)
and that the vehicle ignition is in the ON or ACC position.

## API Reference

```{eval-rst}
.. autoclass:: jumpstarter_driver_obd.driver.OBD()
    :members:

.. autoclass:: jumpstarter_driver_obd.client.OBDClient()
    :members:

.. autoclass:: jumpstarter_driver_obd.driver.OBDConnectionStatus()
    :members:
```
