hondavert-dev/docs/FULL_PROJECT_DOCUMENTATION.md
HVBT Dev 763821171c feat: Add ECU Frame Debug Screen and DTC Screen
- Implemented RawFrameDebugScreen for displaying ECU frame data and diagnostics.
- Created DtcScreen to show active Diagnostic Trouble Codes (DTCs) with detailed descriptions.
- Added DtcRow widget for individual DTC representation.
- Introduced GraphScreen for visualizing sensor data over time with customizable time windows.
- Developed SensorListScreen to display available sensors and their current values.
- Enhanced SettingsScreen with options for Bluetooth connection, ECU protocol selection, polling interval, and theme settings.
- Added AppColors and AppTheme for consistent theming across the application.
- Implemented BtStatusChip to show Bluetooth connection status in the app bar.
- Created RecordFab for starting and stopping data recording sessions.
2026-07-26 23:14:58 +05:30

631 lines
18 KiB
Markdown

# HV BT Dashboard - Full Project Documentation
## 1. Simple Summary
HV BT Dashboard is a Flutter Android app for car/ECU monitoring over Bluetooth.
̥
In plain terms, the app connects to a paired Bluetooth ECU device, asks the ECU for live data many times per second, checks that the received data is valid, converts the raw bytes into readable vehicle values, and shows those values on dashboards, lists, graphs, fault-code screens, and saved recording screens.
The main use case is for a driver, tuner, mechanic, or performance shop that wants to see Honda ECU data such as RPM, speed, throttle, manifold pressure, coolant temperature, intake temperature, battery voltage, fuel/ignition related readings, warning flags, and diagnostic trouble codes.
## 2. What The App Is For
This app is not a general car marketplace or booking app. It is an ECU dashboard and datalogging tool.
It helps a user:
- Connect to a Bluetooth ECU adapter.
- Choose the ECU protocol: S300 or KPro.
- Watch live vehicle sensor data.
- See important values in a large dashboard layout.
- See all supported sensor values in a list.
- Graph selected sensors over time.
- Check active diagnostic trouble codes.
- Record raw ECU frames into local storage.
- View saved recording sessions.
- Start playback controls for saved sessions.
- Change theme, ECU protocol, and polling speed.
## 3. Main Benefits
The business/user benefits are:
- Faster troubleshooting: faults and live readings are visible in one app.
- Safer tuning support: important values like RPM, MAP, TPS, coolant temperature, intake temperature, AFR, trims, and battery voltage can be watched live.
- Better diagnosis: diagnostic trouble codes are decoded into readable descriptions instead of only raw bytes.
- Better review after driving: sessions can be recorded and saved locally.
- Flexible display: users can choose which sensors appear on dashboard tiles and graph panels.
- Works without a backend: data is read from Bluetooth and saved on the phone using SQLite.
- Supports two ECU families: S300 and KPro parser paths are implemented.
## 4. Technology Stack
The app is built with:
- Flutter: mobile app framework.
- Dart: programming language.
- Riverpod: state management.
- flutter_bluetooth_serial: Bluetooth Classic serial communication.
- permission_handler: Android Bluetooth/location permissions.
- fl_chart: graph display.
- sqflite: local SQLite database for datalog sessions.
- path_provider and path: local file/database path handling.
- intl: date formatting for saved sessions.
The project is currently Android-focused. The Android manifest includes Bluetooth and location permissions required for scanning/connecting on Android.
## 5. App Startup Flow
The app starts from `lib/main.dart`.
Startup flow:
1. `main()` starts the Flutter app inside a Riverpod `ProviderScope`.
2. `HvbtApp` builds a `MaterialApp`.
3. The selected theme is read from `themeProvider`.
4. The first screen is `BtPickerScreen`.
So the first thing a user sees is not the dashboard. The user is first asked to connect to an ECU Bluetooth device.
## 6. User Journey
The typical user journey is:
1. User opens the app.
2. App requests Bluetooth and location permissions.
3. App checks whether Bluetooth is turned on.
4. App loads already paired Bluetooth devices.
5. User taps the ECU Bluetooth device.
6. App asks whether the ECU protocol is S300 or KPro.
7. App connects to the selected Bluetooth device.
8. App starts polling the ECU.
9. App receives 128-byte data frames.
10. App validates each frame using NEG8 checksum.
11. App parses the frame into readable sensor values.
12. App navigates to the main dashboard.
13. User can switch between Dashboard, Sensors, Graph, and DTC tabs.
14. User can record a datalog session using the floating record button.
15. User can open saved sessions from the folder icon.
16. User can change protocol/theme/polling settings from the settings icon.
## 7. Main Screens
### 7.1 Bluetooth Picker Screen
File: `lib/ui/screens/bt_picker/bt_picker_screen.dart`
Purpose:
- Ask for required permissions.
- Turn on Bluetooth if needed.
- Show paired Bluetooth devices.
- Let the user pick an ECU device.
- Ask the user to choose S300 or KPro.
- Start the Bluetooth connection.
Important behavior:
- The app only lists paired devices. The user must pair the ECU adapter in Android settings first.
- The screen requests `bluetoothConnect`, `bluetoothScan`, and `locationWhenInUse`.
- If permissions are denied, it shows a red error banner.
- On successful connection, it replaces the screen with `MainNav`.
### 7.2 Main Navigation
File: `lib/ui/widgets/main_nav.dart`
Purpose:
- Provides the main app shell after Bluetooth connection.
- Shows the app bar.
- Shows Bluetooth status.
- Shows saved session and settings buttons.
- Shows bottom navigation.
- Shows the record floating button.
Main tabs:
- Dashboard
- Sensors
- Graph
- DTC
The app uses an `IndexedStack`, so tab state is kept while switching tabs.
### 7.3 Dashboard Screen
Files:
- `lib/ui/screens/dashboard/dashboard_screen.dart`
- `lib/ui/screens/dashboard/dashboard_vertical.dart`
- `lib/ui/screens/dashboard/dashboard_horizontal.dart`
- `lib/ui/screens/dashboard/dashboard_slots_provider.dart`
Purpose:
- Show the live dashboard in a visually useful layout.
- Show a large RPM gauge.
- Show quick sensor tiles.
- Show warning/condition flags.
Portrait layout:
- Large RPM gauge at the top.
- Flag row below it.
- Six sensor tiles in a 2-column grid.
Landscape layout:
- Sensor tiles on left and right.
- Large RPM gauge in the middle.
- Flag row at the bottom.
Default dashboard tile sensors:
- Speed
- Manifold pressure
- Throttle pedal
- Coolant temperature
- Intake air temperature
- Battery voltage
The user can long-press a sensor tile and choose a different sensor for that slot.
### 7.4 Sensor List Screen
File: `lib/ui/screens/sensor_list/sensor_list_screen.dart`
Purpose:
- Show all supported sensor values in a complete list.
This is useful when the dashboard does not show a particular value, but the user still wants to see it.
Supported analog/numeric sensors include:
- RPM
- Speed
- Manifold pressure
- Throttle pedal
- Injector duration
- Timing advance
- Coolant temperature
- Intake air temperature
- Battery voltage
- O2 sensor
- Gear
- Ethanol
- Barometric pressure
- AFR
- Short trim
- Long trim
- Analog input 0 through Analog input 7
### 7.5 Graph Screen
Files:
- `lib/ui/screens/graph/graph_screen.dart`
- `lib/ui/screens/graph/widgets/sensor_graph_panel.dart`
- `lib/core/providers/sensor_history_provider.dart`
Purpose:
- Show live sensor values over time.
- Let the user choose which sensors to graph.
- Let the user choose the visible time window.
Default graph sensors:
- RPM
- MAP
- TPS
The history provider stores up to 18,000 points per sensor in memory. This is live in-memory graph history, not the same thing as saved datalog storage.
### 7.6 DTC Screen
Files:
- `lib/ui/screens/dtc/dtc_screen.dart`
- `lib/core/protocol/dtc_map.dart`
Purpose:
- Decode ECU error bytes into readable diagnostic trouble codes.
- Show whether there are active faults.
If there are no codes, the screen shows an all-clear state.
If codes are active, the screen lists code and description, for example `P0130 - O2 Sensor (front)`.
S300 supports 4 error bytes in this app. KPro supports 18 error bytes in this app.
### 7.7 Saved Sessions Screen
Files:
- `lib/ui/screens/datalog/datalog_list_screen.dart`
- `lib/ui/screens/datalog/datalog_playback_bar.dart`
- `lib/core/datalog/datalog_db.dart`
- `lib/core/datalog/datalog_recorder.dart`
- `lib/core/datalog/datalog_player.dart`
Purpose:
- Show recorded sessions.
- Show session date, ECU type, frame count, and duration.
- Delete old sessions.
- Load a saved session into playback.
- Show playback progress, play/pause/stop controls, seek slider, and speed selector.
Important current note:
The player has a stream that can replay saved frames, and the UI has playback controls. However, the current live sensor provider listens to the Bluetooth frame stream, not the datalog player stream. That means the saved-session playback control layer exists, but the dashboard/sensor/graph screens are not currently wired to consume playback frames as a replacement for live Bluetooth frames.
### 7.8 Settings Screen
File: `lib/ui/screens/settings/settings_screen.dart`
Purpose:
- Show current Bluetooth connection state.
- Disconnect Bluetooth.
- Choose ECU protocol.
- Choose polling interval.
- Choose theme.
- Show app information.
Available ECU protocols:
- S300
- KPro
Available polling intervals:
- 50 ms, about 20 Hz
- 100 ms, about 10 Hz
- 200 ms, about 5 Hz
Available themes:
- Red - Dark
- Red - Light
- Green - Dark
- Green - Light
## 8. Bluetooth And ECU Data Flow
This is the most important technical flow in the app.
Simple version:
The app asks the ECU for data. The ECU replies with bytes. The app checks the bytes. Then the app converts them into numbers and displays them.
Detailed flow:
1. `BtPickerScreen` asks the user to select a paired Bluetooth device.
2. `BtNotifier.connect()` calls `BtService.connect()`.
3. `BtService` opens a Bluetooth Classic RFCOMM/SPP connection.
4. `BtPoller` starts a timer.
5. On each timer tick, `BtPoller` sends a request command to the ECU.
6. The ECU sends back raw bytes.
7. `BtPoller` collects those bytes into a buffer.
8. It looks for a frame starting with `0x1B`.
9. It extracts 128-byte frames.
10. It validates the frame using `validateFrame()`.
11. Valid frames are sent to `BtNotifier.frameStream`.
12. `sensorStateProvider` parses each frame.
13. UI screens read `latestSensorProvider` and update.
Request bytes:
- S300 request: `[0x1B, 0x00, 0xE5]`
- KPro request: `[0x1B, 0x01, 0xE4]`
Frame size:
- 128 bytes
Default polling:
- 100 ms, roughly 10 updates per second
## 9. Parsing Logic
The app has two parser files:
- `lib/core/protocol/s300_parser.dart`
- `lib/core/protocol/kpro_parser.dart`
Both parsers produce the same output model: `SensorState`.
That is important because the UI does not need to know where the values came from. The UI only reads fields like `rpm`, `vss`, `map`, `tps`, `ect`, and `bat`.
S300 and KPro use different byte offsets and formulas. The parser hides that complexity.
Example:
- S300 RPM is read from bytes 3 and 4.
- KPro RPM is read from bytes 2 and 3, then divided by 4.
The result is still exposed to the UI as `state.rpm`.
## 10. SensorState Model
File: `lib/core/protocol/sensor_state.dart`
`SensorState` is the central live-data model.
It contains:
- Numeric sensors.
- Boolean flags.
- Raw error bytes.
- Timestamp.
Numeric examples:
- `rpm`
- `vss`
- `map`
- `tps`
- `inj`
- `ign`
- `ect`
- `iat`
- `bat`
- `o2`
- `gear`
- `eth`
- `pa`
- `afr`
- `strim`
- `ltrim`
- `ain0` through `ain7`
Flag examples:
- MIL
- Fuel Cut
- FAN Out
- VTEC
- Knock
- Rev Limit
- Launch
## 11. State Management
The app uses Riverpod providers.
Important providers:
- `btProvider`: Bluetooth connection status and frame stream.
- `pairedDevicesProvider`: paired Bluetooth devices.
- `settingsProvider`: ECU type and polling interval.
- `sensorStateProvider`: parsed live sensor stream.
- `latestSensorProvider`: latest available sensor state for UI.
- `sensorHistoryProvider`: graph history.
- `dashboardSlotsProvider`: selected dashboard tile sensors.
- `recordingProvider`: datalog recording status.
- `sessionListProvider`: saved datalog sessions.
- `playbackProvider`: saved session playback state.
- `themeProvider`: selected theme.
In simple terms, providers are the app's shared memory. Screens watch providers, and when the provider changes, the screen updates.
## 12. Datalog Recording
The datalog recorder saves raw validated ECU frames, not only final display values.
Recording flow:
1. User taps the floating record button.
2. `RecordingNotifier.startRecording()` starts a new session.
3. The recorder listens to `BtNotifier.frameStream`.
4. Every incoming frame is added to a batch.
5. Every 500 ms, the batch is written to SQLite.
6. User taps the record button again to stop.
7. The app writes the end time and frame count to the session row.
8. Saved sessions list is refreshed.
Database file:
- `hvbt_datalog.db`
Database tables:
- `sessions`: one row per recording session.
- `frames`: raw frame blobs linked to a session.
This approach is useful because raw frames can later be replayed or re-parsed if parser logic improves.
## 13. Local Storage
The app uses local phone storage only.
There is no backend API in this project.
Stored locally:
- Datalog sessions.
- Raw ECU frames.
Currently in-memory only:
- Theme selection.
- ECU protocol selection.
- Polling interval.
- Dashboard tile slot choices.
- Graph sensor choices.
Because these settings are not persisted with shared preferences in the current implementation, they reset when the app restarts.
## 14. Android Permissions
The Android manifest requests:
- `BLUETOOTH`
- `BLUETOOTH_ADMIN`
- `BLUETOOTH_CONNECT`
- `BLUETOOTH_SCAN`
- `ACCESS_FINE_LOCATION`
- `ACCESS_COARSE_LOCATION`
The app also requests permissions at runtime from the Bluetooth picker screen.
Why location permission appears:
On Android, Bluetooth scanning and device discovery have historically been tied to location permission. Even though the app is not a location app, Android may require this permission for Bluetooth workflows.
## 15. Project Folder Map
Important folders:
- `lib/main.dart`: app entry point.
- `lib/core/bluetooth`: Bluetooth connection and polling.
- `lib/core/protocol`: ECU parsing, checksum, DTC map, temperature table.
- `lib/core/providers`: Riverpod state providers.
- `lib/core/models`: sensor definitions and datalog session model.
- `lib/core/datalog`: SQLite database, recording, playback.
- `lib/ui/screens`: app screens.
- `lib/ui/widgets`: shared UI widgets.
- `lib/ui/theme`: colors and theme setup.
- `test`: parser, checksum, DTC, and utility tests.
- `android`: Android build and permission configuration.
## 16. Testing
The project has Flutter tests for important protocol logic.
Existing tests cover:
- S300 parser behavior.
- KPro parser behavior.
- NEG8 checksum behavior.
- Temperature table behavior.
- DTC map decoding.
These tests are valuable because parser bugs can display wrong vehicle data. The parser layer is one of the highest-risk parts of the app.
Run tests with:
```powershell
flutter test
```
## 17. Build And Run Commands
Run the app on a connected device in debug mode:
```powershell
flutter run
```
Run the app in release mode:
```powershell
flutter run --release
```
Build a release APK:
```powershell
flutter build apk --release
```
Build an Android App Bundle:
```powershell
flutter build appbundle --release
```
Do not use:
```powershell
flutter run build --release
```
That command is wrong because Flutter treats `build` as a Dart target file.
## 18. Current Limitations And Honest Notes
These are not complaints. They are useful project facts for future development.
- Saved playback is not currently wired into `sensorStateProvider`, so dashboard screens still listen to live Bluetooth frames.
- Settings are not persisted after restart, even though `shared_preferences` is included as a dependency.
- Dashboard tile choices are not persisted after restart.
- Graph selected sensors and time window are not persisted after restart.
- The app is Android-focused because it uses `flutter_bluetooth_serial` and Android Bluetooth permissions.
- The app lists already paired devices; it does not provide a full in-app Bluetooth pairing flow.
- Settings screen shows app info as `v1.4.0 - Phase 4`, while `pubspec.yaml` version is `1.3.0+4`; this should be aligned before release.
## 19. Plain-English Explanation For Non-Technical People
Think of the ECU as the car's engine computer.
The app works like a translator:
1. It connects to the ECU through Bluetooth.
2. It repeatedly asks, "What is happening right now?"
3. The ECU replies with a block of computer bytes.
4. The app checks if the reply is valid.
5. The app translates those bytes into readable values.
6. The app shows those values as gauges, lists, graphs, and warning codes.
For example, the ECU may send bytes that mean "engine is at 3000 RPM." A normal person cannot read that raw data, so the app converts it into a clean dashboard value.
## 20. Feature List
Implemented user-facing features:
- Bluetooth permission request.
- Paired Bluetooth device listing.
- Bluetooth connection to ECU adapter.
- ECU protocol selection.
- S300 polling command.
- KPro polling command.
- 128-byte frame collection.
- NEG8 checksum validation.
- S300 parser.
- KPro parser.
- Live RPM gauge.
- Portrait dashboard.
- Landscape dashboard.
- Six customizable dashboard sensor slots.
- Live flag indicators.
- Full sensor list.
- Live graph screen.
- Add/remove graph sensors.
- Select graph time window.
- DTC decoding screen.
- S300 DTC map.
- KPro DTC map.
- Local datalog recording.
- Saved datalog session list.
- Swipe-to-delete saved sessions.
- Playback controls for saved sessions.
- Polling interval settings.
- Theme settings.
- Disconnect action.
- Bluetooth status chip.
## 21. Suggested Next Improvements
High-value next improvements:
- Wire datalog playback frames into the same parser/display pipeline used by live Bluetooth.
- Persist user settings using `shared_preferences`.
- Persist dashboard tile selections.
- Persist graph sensor selections.
- Add export/share for datalog sessions.
- Add CSV export for recorded frames or parsed sensor values.
- Add clearer connection lost handling and auto-reconnect behavior.
- Align app version in UI and `pubspec.yaml`.
- Add user-facing explanation for S300 vs KPro selection.
- Add tests for datalog database and recorder behavior.
## 22. One-Line Pitch
HV BT Dashboard turns raw Honda ECU Bluetooth data into a practical live dashboard, diagnostic tool, graphing tool, and local datalog recorder.