Parsers

class obdii.parsers.formula.SafeEvaluator(variables)[source]

Bases: NodeVisitor

A safe evaluator that only allows basic math operations.

operators = {<class 'ast.Add'>: <built-in function add>, <class 'ast.BitXor'>: <built-in function xor>, <class 'ast.Div'>: <built-in function truediv>, <class 'ast.FloorDiv'>: <built-in function floordiv>, <class 'ast.Mod'>: <built-in function mod>, <class 'ast.Mult'>: <built-in function mul>, <class 'ast.Pow'>: <built-in function pow>, <class 'ast.Sub'>: <built-in function sub>}
visit_BinOp(node: BinOp) Any[source]
visit_UnaryOp(node: UnaryOp) Any[source]
visit_Name(node: Name) Any[source]
visit_Constant(node: Constant) Any[source]
visit_Expr(node: Expr) Any[source]
generic_visit(node) NoReturn[source]

Called if no explicit visitor function exists for a node.

class obdii.parsers.formula.Formula(expression: str)[source]

Bases: object

Represents a mathematical formula based on a string expression.

Example

# 0B (hex) | 11 (dec) -> A
# 40 (hex) | 64 (dec) -> B
parsed_data = [(b'0B', b'40')]

formula = Formula("(256*A+B)/4")
result = formula(parsed_data)
# (256 * 11 + 64)/4

>>> result
720.0
__init__(expression: str)[source]

Initialize the Formula with a given expression.

Parameters:

expression (str) – The expression string to evaluate. Variable names are converted to uppercase.

__call__(parsed_data: List[Tuple[bytes, ...]]) int | float[source]

Evaluate the formula on the given parsed_data.

Parameters:

parsed_data (BytesRows) – The parsed data to evaluate the formula against.

class obdii.parsers.formula.MultiFormula(*expressions: str)[source]

Bases: object

Represents multiple mathematical formulas based on string expressions.

Example

# 8F (hex) | 143 (dec) -> A
# 7D (hex) | 125 (dec) -> B
# 95 (hex) | 149 (dec) -> C
# 80 (hex) | 128 (dec) -> D
# 6F (hex) | 111 (dec) -> E
parsed_data = [(b"8F", b"7D", b"95", b"80", b"6F")]

engine_torque = MultiFormula("A-125", "B-125", "C-125", "D-125", "E-125")
result = engine_torque(parsed_data)

>>> result
[18, 0, 24, 3, -14]
__init__(*expressions: str) None[source]

Initialize formulas based on given expressions.

Parameters:

*expressions (str) – Expression strings to evaluate. Variable names are converted to uppercase.

__call__(parsed_data: List[Tuple[bytes, ...]]) List[int | float][source]

Evaluate all formulas on the given parsed_data.

Parameters:

parsed_data (BytesRows) – The parsed data to evaluate the formulas against.

class obdii.parsers.pids.SupportedPIDS(base_pid: int)[source]

Bases: object

Parse supported PIDs from the response data.

Each bit in the 4 byte (32 bit) response represents support for one PID, starting from the Base PID. A bit set to 1 indicates the PID is supported, 0 means it is not. Bits are read from most-significant to least-significant.

Example

parsed_data = [(b"BE", b"1F", b"A8", b"13")]
# B    E    1    F    A    8    1    3
# 1011 1110 0001 1111 1010 1000 0001 0011

supported_pids = SupportedPIDS(0x01)
result = supported_pids(parsed_data)

>>> result
[0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x1C, 0x1F, 0x20]
__init__(base_pid: int) None[source]

Initialize SupportedPIDS with a given base PID.

Parameters:

base_pid (int) – The base PID from which the support bits start.

__call__(parsed_data: List[Tuple[bytes, ...]]) List[int][source]

Parse supported PIDs from the response data.

Parameters:

parsed_data (BytesRows) – The parsed response data containing hex byte strings.

Returns:

List of supported PIDs.

Return type:

List[int]

class obdii.parsers.pids.EnumeratedPIDS(mapping: Dict[int | Iterable[int], Any])[source]

Bases: object

Map parsed data bytes to enumerated values.

Example

parsed_data = [(b"00", b"00")]

fuel_system_status = EnumeratedPIDS(
    {
        0: "The motor is off",
        1: "Open loop due to insufficient engine temperature",
        2: "Closed loop, using oxygen sensor feedback to determine fuel mix",
        4: "Open loop due to engine load OR fuel cut due to deceleration",
        8: "Open loop due to system failure",
        16: "Closed loop, using at least one oxygen sensor but there is a fault in the feedback system",
    }
)
result = fuel_system_status(parsed_data)

>>> result
[(0, "The motor is off"), (0, "The motor is off")]
__init__(mapping: Dict[int | Iterable[int], Any]) None[source]

Initialize EnumeratedPIDS with a mapping dictionary.

Parameters:

mapping (Dict[Union[int, Iterable[int]], Any]) – A dictionary mapping byte values to their corresponding enumerated meanings.

__call__(parsed_data: List[Tuple[bytes, ...]]) List[Tuple[int, Any]][source]

Map parsed data bytes to enumerated values.

Parameters:

parsed_data (BytesRows) – The parsed response data containing hex byte strings.

Returns:

List of tuples containing the byte value and its corresponding enumerated meaning.

Return type:

List[Tuple[int, Any]]