2026-04-01 20:16:30 -04:00
2026-04-01 20:12:29 -04:00
2026-04-01 19:34:26 -04:00
2026-04-01 19:34:26 -04:00
2026-04-01 20:16:30 -04:00
2026-04-01 19:34:26 -04:00
2026-04-01 20:12:29 -04:00
2026-04-01 19:34:26 -04:00

OBD2 Terminal Dashboard

This repository contains a Textual-based terminal dashboard for querying an OBD-II adapter and presenting live vehicle telemetry alongside raw command output.

scanbus.py is intentionally excluded from this README.

What It Does

  • Displays live dashboard metrics for speed, RPM, fuel level, oil temperature, and coolant temperature.
  • Renders a command table for OBD modes 01, 02, 03, 04, 06, 07, and 09.
  • Polls commands asynchronously with a global queries-per-second limit.
  • Deduplicates concurrent reads of the same OBD command.
  • Caches command results using a default TTL plus per-command overrides from command_ttl.conf.
  • Supports a simulated mode for UI development without a physical adapter.
  • Streams application logs inside the terminal UI.

Repository Layout

  • obd2_tui.py: main Textual app, CLI entry point, keyboard bindings, command polling, and inline TTL editing.
  • obd2_interface.py: async OBD abstraction, connection lifecycle, rate limiting, caching, TTL config reloads, and simulation support.
  • models.py: Pydantic models for the live telemetry report and scan definitions.
  • ui.css: Textual stylesheet for the dashboard, command table, and log panel.
  • command_ttl.conf: command-specific cache TTL overrides in milliseconds.
  • test.py: unit tests for report normalization, interface behavior, caching, TTL updates, simulation, and UI helpers.
  • requirements.txt: Python dependencies.

Architecture

The application has two main layers:

  1. OBD2App in obd2_tui.py

    • Builds the terminal UI with Textual.
    • Polls a small set of key telemetry commands continuously for the metric cards.
    • Polls the currently visible rows in the selected OBD mode table.
    • Lets the user edit a selected command's cache TTL from the UI.
  2. OBD2Interface in obd2_interface.py

    • Connects to the adapter through python-OBD.
    • Serializes outbound queries through a worker queue.
    • Enforces a global rate limit.
    • Maintains a TTL cache keyed by command name.
    • Watches command_ttl.conf and hot-reloads TTL overrides.

SimulatedOBD2Interface swaps in a fake connection that generates dynamic values for development and testing.

Requirements

  • Python 3.11+ recommended
  • An ELM327-compatible OBD-II adapter for real vehicle data
  • Terminal support suitable for a Textual application

Install dependencies:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Running

Run against a real OBD adapter:

python3 obd2_tui.py

Run in simulated mode:

python3 obd2_tui.py --simulated

Optional flags:

  • --qps: maximum OBD queries per second across the app. Default: 10.0
  • --ttl-config: path to the TTL override file. Default: command_ttl.conf

Example:

python3 obd2_tui.py --simulated --qps 25 --ttl-config command_ttl.conf

UI Behavior

The dashboard is composed of:

  • Metric cards for the five primary telemetry values
  • A command table for the selected OBD mode
  • A TTL editor bound to the currently highlighted command
  • An in-app log panel

The polling strategy is selective:

  • Core telemetry commands are always queried so the metric cards stay current.
  • The mode table queries only commands that are currently visible in the viewport.
  • Duplicate requests for the same command are coalesced through the interface queue and cache.

Keyboard Controls

  • q: quit
  • b: toggle metric card border style
  • e: focus the TTL editor
  • escape: return focus to the command table
  • left / right: previous or next OBD mode
  • shift+up / shift+down: jump to top or bottom of the table
  • 1, 2, 3, 4, 6, 7, 9: switch directly to that OBD mode

TTL Configuration

command_ttl.conf uses the format:

COMMAND_NAME,ttl_ms

Examples:

SPEED,10
RPM,10
FUEL_LEVEL,5000
GET_DTC,86400000

Notes:

  • TTL values are stored in milliseconds.
  • A value of 0 effectively disables caching for that command.
  • The app reloads the file automatically while running.
  • Editing a TTL in the UI writes the updated value back to the configured TTL file.

Testing

Run the unit tests with:

python3 -m unittest -v test.py

The tests cover:

  • Report value normalization
  • Query rate limiting
  • Cache hit and cache expiry behavior
  • TTL override parsing and persistence
  • Simulated connection behavior
  • Display formatting and duration parsing helpers

Current Environment Note

In the current workspace environment, python3 -m unittest -v test.py fails immediately because pydantic is not installed. After installing dependencies from requirements.txt, the test command should be rerun.

Development Notes

  • Logging is routed into the Textual RichLog panel through a custom logging handler.
  • The codebase uses Report as the shared mutable telemetry state for the UI.
  • command_ttl.conf is large because it predefines cache behavior for many standard OBD commands.
  • obd2_interface.py also contains a non-TUI __main__ path that continuously logs report snapshots, but the primary entry point for normal use is obd2_tui.py.
Description
No description provided
Readme 53 KiB
Languages
Python 98%
CSS 2%