Status: implemented in CarDash 0.6.0; OBD hardware still needs a real-car test. Last updated: 2026-10-29
CarDash optionally reads live data from a Bluetooth Classic ELM327 adapter in the car's OBD-II port and shows it on the home page. When OBD does not provide an ambient temperature, an optional location-based weather fallback can fill the temperature row.
| Value | PID | Notes |
|---|---|---|
| Vehicle speed, km/h | 0D |
Digital home readout |
| Throttle, % | 49, fallback 11 |
Horizontal bar |
| MAF, g/s | 10 |
Rolling fuel-economy input |
| Ambient temperature, °C | 46 |
OBD temperature row |
The economy figure is a 5 km rolling average in L/100 km. It uses petrol
constants (stoichiometric AFR 14.7, 745 g/L), ignores MAF on a closed-throttle
coast above 10 km/h, and shows — until at least 0.5 km has accumulated.
04/08 writes; CarDash is read-only.| # | Decision |
|---|---|
| D1 | Bluetooth Classic SPP only; only devices already paired in Android Settings. No scan UI. |
| D2 | Throttle uses accelerator 49, falling back to plate 11. |
| D3 | Metric L/100 km only. |
| D4 | Small live card above the volume card; temperature row below the date. |
| D5 | Rolling window resets on disconnect or a sample gap over 30 s. |
| D6 | No fuel level or range. |
| D7 | OBD ambient wins over weather whenever it is present and fresh. |
| Feature | Manifest | Runtime |
|---|---|---|
| Bluetooth 29–30 | BLUETOOTH, BLUETOOTH_ADMIN (maxSdkVersion="30") |
install-time |
| Bluetooth 31+ | BLUETOOTH_CONNECT |
requested from the Car data card |
| Weather | INTERNET, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION |
location requested when the weather toggle is enabled |
There is no BLUETOOTH_SCAN. The app lists bonded devices only and requests
Bluetooth permission from the Car data card before listing them.
Location is one-shot. Coordinates and place names are held only in memory for
the current weather value; they are not persisted. The adapter address and the
weather toggle are persisted in SettingsRepository.
Kotlin
TelemetryBridge MethodChannel "com.wasp.cardash_launcher/telemetry"
- listBondedDevices / isBluetoothEnabled / ensureBluetoothPermission
- connectObd(mac) / disconnectObd / getObdState
- ensureLocationPermission / getLocation (last-known or single fix + Geocoder)
ObdService one worker thread over BluetoothSocket/RFCOMM SPP
- handshake ATZ, ATE0, ATL0, ATS0, ATSP0
- request/response serialized, prompt-terminated
- latest snapshot polled by Dart
Dart
NativeTelemetryBridge platform boundary
ObdController connection lifecycle, 1 s snapshot polling, status
ObdEconomy MAF/speed integrator with 5 km window
WeatherController toggle, permission, one-shot location, weather cache
WeatherService keyless Open-Meteo current temperature_2m
TelemetryBridge models BluetoothDeviceInfo / LocationReading / ObdState
SettingsRepository obd.adapterAddress, weather.locationTemperature
The native ObdService polls speed, throttle and MAF roughly once per second;
ambient temperature is refreshed every 30 poll cycles. A snapshot carries
updatedAt; the Dart side treats data older than five seconds as stale and
hides the live card. Connection failures surface as a short Settings status and
keep the dashboard quiet.
Outside, 7°CSofia, 7°C (or Current location, 7°C)OBD card in the left column above the media-volume card, only while fresh telemetry exists:
● OBD-II LIVE
44 km/h
Throttle 22%
[========------------------]
Rolling economy 7.5 L/100 km
The card and row disappear cleanly when off/no adapter/no fresh data. The 16-button grid keeps its own space.
None and paired Bluetooth Classic
devices. Find/Allow requests Bluetooth permission and refreshes the list.Selecting a device persists its MAC address and connects immediately when the
app is active. Selecting None disconnects. Polling stops when CarDash leaves
the foreground and reconnects on resume.
WeatherController:
TelemetryBridge.getLocation.Geocoder.https://api.open-meteo.com/v1/forecast?...¤t=temperature_2m&timezone=auto
Any failure clears the temperature and hides the row. No API key, account or coordinates are stored.
-40/215 sentinel values are rejected.Ukiah, 17°C during implementation).