Core

class obdii.Command(mode: Mode | int | str, pid: Template | int | str, expected_bytes: int | Iterable[int] = 0, min_values: int | float | Iterable[int | float] | None = ..., max_values: int | float | Iterable[int | float] | None = ..., units: str | Iterable[str] | None = ..., resolver: Callable | None = ...)[source]

Bases: object

__init__(mode: Mode | int | str, pid: Template | int | str, expected_bytes: int | Iterable[int] = 0, min_values: int | float | Iterable[int | float] | None = ..., max_values: int | float | Iterable[int | float] | None = ..., units: str | Iterable[str] | None = ..., resolver: Callable | None = ...) None[source]

Initialize a Command instance.

Parameters:
  • mode (Union[Mode, int, str]) – Command mode to be used.

  • pid (Union[Template, int, str]) – Command PID (Parameter Identifier) to be used.

  • expected_bytes (OneOrMany[int]) – The number of bytes expected in the response.

  • min_values (Optional[OneOrMany[Real]]) – Minimum valid values for the command’s parameters.

  • max_values (Optional[OneOrMany[Real]]) – Maximum valid values for the command’s parameters.

  • units (Optional[OneOrMany[str]]) – The units for the command’s response.

  • resolver (Optional[Callable]) – A resolver function for custom response handling.

__call__(*args, **kwargs) Command[source]

Formats the command with the provided positional or keyword arguments.

Parameters:
  • *args (Any) – Positional arguments corresponding to placeholders in the command’s PID template.

  • **kwargs (Any) – Keyword arguments corresponding to placeholders in the command’s PID template.

Returns:

A new Command instance with the formatted PID.

Return type:

Command

build(early_return: bool = False) bytes[source]

Builds the query to be sent to the ELM327 device as a byte string. (The ELM327 is case-insensitive, ignores spaces and all control characters.)

Parameters:

early_return (bool) – Whether to include the early return digit in the command. If set to True, appends a hex digit representing the expected number of responses in the query. Defaults to False.

Returns:

The formatted query as a byte string, ready to be sent to the ELM327 device.

Return type:

bytes

Raises:

ValueError – If the PID is a Template, which means your command has likely not been formatted.

class obdii.Connection(transport: str | Tuple[str, str | int] | TransportBase, protocol: Protocol = Protocol.AUTO, auto_connect: bool = True, smart_query: bool = False, early_return: bool = False, *, log_handler: Handler | None = ..., log_formatter: Formatter = ..., log_level: int = ..., log_root: bool = False, **kwargs)[source]

Bases: object

__init__(transport: str | Tuple[str, str | int] | TransportBase, protocol: Protocol = Protocol.AUTO, auto_connect: bool = True, smart_query: bool = False, early_return: bool = False, *, log_handler: Handler | None = ..., log_formatter: Formatter = ..., log_level: int = ..., log_root: bool = False, **kwargs) None[source]

Initialize connection settings and optionally auto-connect.

Parameters:
  • transport (Union[str, Tuple[str, Union[str, int]], TransportBase]) – Can be represented as a string for serial ports (e.g., “COM5”, “/dev/ttyUSB0”, “/dev/rfcomm0”), or as a tuple for network transports (e.g., (“<hostname>”, <port>)), or as an instance of a subclass of TransportBase.

  • protocol (Protocol) – The protocol to use for communication.

  • auto_connect (bool) – If True, connect to the adapter immediately.

  • smart_query (bool) – If True, send repeat command when the same command is issued again.

  • early_return (bool) – If set to true, the ELM327 will return immediately after sending the specified number of responses specified in the command (expected_bytes). Works only with ELM327 v1.3 and later.

  • log_handler (logging.Handler) – Custom log handler for the logger.

  • log_formatter (logging.Formatter) – Formatter to use with the given log handler.

  • log_level (int) – Logging level for the logger.

  • log_root (bool) – Whether to set up the root logger.

  • **kwargs (dict) – Additional keyword arguments forwarded to the transport’s constructor.

connect(**kwargs) None[source]

Establishes a connection to the device using the configured transport and runs the initialization sequence.

Parameters:

**kwargs – Additional keyword arguments forwarded to the transport’s connect method.

is_connected() bool[source]

Checks if the transport connection is open.

Returns:

True if the connection is active.

Return type:

bool

query(command: Command) Response[source]

Send a command and wait for the response.

Parameters:

command (Command) – Command to send.

Returns:

Parsed response from the adapter.

Return type:

Response

wait_for_response(context: Context) Response[source]

Wait for a raw response from the transport and parses it using the protocol handler.

Parameters:

context (Context) – Context to use for parsing.

Returns:

Parsed response or raw fallback response.

Return type:

Response

close() None[source]

Closes the transport connection.

__enter__() Connection[source]

Support usage as a context manager.

Returns:

The connection instance itself.

Return type:

Connection

__exit__(exc_type: Type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) None[source]

Close the connection when exiting the context.

class obdii.Context(command: obdii.command.Command, protocol: obdii.protocol.Protocol, timestamp: float = <factory>)[source]

Bases: object

command: Command
protocol: Protocol
timestamp: float
class obdii.Mode(*values)[source]

Bases: BaseEnum

NONE = ''

Special mode used for the REPEAT command

AT = 'AT'

Special mode to send AT commands

REQUEST = 1

Request current data

FREEZE_FRAME = 2

Request freeze frame data

STATUS_DTC = 3

Request stored DTCs (Diagnostic Trouble Codes)

CLEAR_DTC = 4

Clear/reset DTCs (Diagnostic Trouble Codes)

O2_SENSOR = 5

Request oxygen sensor monitoring test results

PENDING_DTC = 6

Request DTCs (Diagnostic Trouble Codes) pending

CONTROL_MODULE = 7

Request control module information

O2_SENSOR_TEST = 8

Request oxygen sensor test results

VEHICLE_INFO = 9

Request vehicle information

PERMANENT_DTC = 10

Request permanent DTCs (Diagnostic Trouble Codes)

class obdii.Protocol(*values)[source]

Bases: BaseEnum

UNKNOWN = -1

Unknown protocol

AUTO = 0

Automatically determine the protocol

SAE_J1850_PWM = 1

SAE J1850 PWM (41.6 kbaud)

SAE_J1850_VPW = 2

SAE J1850 VPW (10.4 kbaud)

ISO_9141_2 = 3

ISO 9141-2 (5 baud init, 10.4 kbaud)

ISO_14230_4_KWP = 4

ISO 14230-4 KWP (5 baud init, 10.4 kbaud)

ISO_14230_4_KWP_FAST = 5

ISO 14230-4 KWP (fast init, 10.4 kbaud)

ISO_15765_4_CAN = 6

ISO 15765-4 CAN (11 bit ID, 500 kbaud)

ISO_15765_4_CAN_B = 7

ISO 15765-4 CAN (29 bit ID, 500 kbaud)

ISO_15765_4_CAN_C = 8

ISO 15765-4 CAN (11 bit ID, 250 kbaud)

ISO_15765_4_CAN_D = 9

ISO 15765-4 CAN (29 bit ID, 250 kbaud)

SAE_J1939_CAN = 10

SAE J1939 CAN (29 bit ID, 250* kbaud), default settings (user adjustable)

USER1_CAN = 11

USER1 CAN (11* bit ID, 125* kbaud), default settings (user adjustable)

USER2_CAN = 12

USER2 CAN (11* bit ID, 50* kbaud), default settings (user adjustable)

class obdii.Response(context: obdii.response.Context, raw: bytes, timestamp: float = <factory>, messages: Dict[bytes, List[int]] | None=None, unparsed: List[int] | None = None, value: Any | None = None)[source]

Bases: ResponseBase

messages: Dict[bytes, List[int]] | None = None
unparsed: List[int] | None = None
value: Any | None = None
property min_values: int | float | Iterable[int | float] | None
property max_values: int | float | Iterable[int | float] | None
property units: str | Iterable[str] | None
class obdii.ResponseBase(context: obdii.response.Context, raw: bytes, timestamp: float = <factory>)[source]

Bases: object

context: Context
raw: bytes
timestamp: float
class obdii.Template(template: str)[source]

Bases: object

Represents a string template with named placeholders that can be substituted with values.

The template definition uses curly braces {}, each placeholder follows the format {name:type}, where name is the parameter name and type is an optional type specifier.

The following type specifiers are supported: - str: Converts the value to a string. - int: Converts the value to an integer. - hexN: Converts the value to a hexadecimal string, padded to N digits (e.g., hex2 for 2 digits).

Few rules and assumptions apply when defining and substituting templates: - Placeholder names must be unique within a template. - If a type specifier is not provided, the value will be treated as a string. - When substituting values, either positional or keyword arguments can be used, but not both. - If using positional arguments, the number of arguments must match the number of placeholders. - If using keyword arguments, all placeholder names must be provided.

Example

t = Template("AT {a:str} {b:int} {c:hex4} {d}")
r = t.substitute(a=1, b=2.2, c=3, d="four")
# or
r = t.substitute(1, 2.2, 3, "four")

>>> r
"AT 1 2 0003 four"
PARAM_RE = re.compile('\\{\\s*(?P<name>\\w+)\\s*(?::\\s*(?P<type>\\w+))?\\s*\\}')
HEX_RE = re.compile('hex(?P<width>\\d*)')
TYPE_MAP: Dict[str | Pattern, Callable[[Dict, Any], str]] = {'int': <function Template.<lambda>>, 'str': <function Template.<lambda>>, re.compile('hex(?P<width>\\d*)'): <function Template.<lambda>>}
substitute(*args, **kwargs) str[source]

Substitute the placeholders in the template with the provided values.

The substitution must use either positional or keyword arguments, not both.

Parameters:
  • *args (Any) – Positional arguments corresponding to the placeholders in the template.

  • **kwargs (Any) – Keyword arguments corresponding to the placeholders in the template.

  • Returns – str: The template string with placeholders replaced by the provided values.