Read-only live energy dashboard and local trip analyser for the SAIC MG4 head unit.
⚠️ No warranty, no liability. Telemetry may be wrong, delayed or unavailable. Never use this app as the sole basis for a range or charging decision. See DISCLAIMER.md.
- Overview
- Features
- Requirements
- How it works
- Trip export formats
- Install
- Configuration
- Building
- Project layout
- Project documents
- Security
- Contributing
- Legal
EVChargePilot is an offline EVSuite application for Android Automotive OS 9. It reads typed,
firmware-aware vehicle capabilities from EVHardware and renders unavailable readings as —.
It does not write to the vehicle and does not contain network or update code.
- Vehicle-reported SOC and range.
- Speed, outside temperature and climate state.
- Parked-only trip recording controls.
- Distance and duration calculated locally.
- Battery power, pack temperature and charging state when exposed by the current firmware.
- Energy and regeneration integration from the shared EVHardware power convention.
- Atomic, app-private trip history and in-app crash diagnostics.
Every signal remains best-effort: unsupported or unreadable properties are displayed as —,
never zero. Arrival SOC, charger routing and energy-source attribution remain outside this
initial milestone.
- SAIC MG4 head unit running Android Automotive OS 9 or a compatible test device.
- Android API 28 or newer.
- Platform signing for privileged car-property permissions where required by the firmware.
EVHardware's EnergyTelemetryReader produces one coherent nullable snapshot per second.
Its shared EnergyTripAccumulator integrates adjacent snapshots, rejecting gaps longer than
five seconds instead of inventing motion. EnergyTripHistoryStore writes a bounded history
through a unique temporary file and atomic rename.
While a trip is active, a foreground service owns the sampler so recording continues when the driver opens another app. A trip's reported duration is the time actually covered by usable samples, not wall clock: a suspended sampler adds nothing to duration, distance or energy, so consumption averages compare values measured over the same interval.
The trip history can export one trip or the full bounded ledger without network or storage
permission. Exports are written atomically under the app-private files/exports/ directory;
the completed absolute path is shown in the app for an explicit adb pull. Share file opens
Android's chooser with temporary read access to that one file through FileProvider.
CSV contains summary rows only, in this exact order:
started_at_utc,ended_at_utc,recorded_duration_seconds,distance_km,start_soc_percent,end_soc_percent,consumed_kwh,regenerated_kwh,average_consumption_kwh_per_100km
Times are ISO-8601 UTC, duration is seconds, distance is kilometres, SOC is percent, energy is
kWh, and average consumption is kWh/100 km. An unavailable value is an empty cell, never 0.
JSON export schema version 1 contains exportedAtUtc and the complete stored trip objects:
each summary plus its retained sample track. Unavailable nullable readings are explicit null.
Both formats are limited to the history ceiling of 200 trips and 2 MiB per export. The export
directory retains the eight newest generated files so repeated exports cannot grow without bound.
Install only a signed APK you trust, while the vehicle is parked. Stable releases do not self-update.
There is no configuration in v0.1. Start or stop a trip from the right-hand rail while the vehicle reports zero speed.
With mise:
mise install
mise run bootstrap
mise run test
mise run buildAndroid has no Automotive API 28 system image, so local validation uses two complementary profiles. Neither replaces testing on every supported vehicle firmware:
mise run emulator-setup # one-time image download and AVD creation
mise run emulator-car # API 33 Automotive: car-service lifecycle
mise run emulator-screen # API 28, 1920x720: target OS and driver layout
mise run run # build, install and launch on the connected device
mise run logs # focused application and EVHardware logs
mise run emulator-stopThe emulators do not expose the MG4 vendor services or signals. Seeing — for unavailable
telemetry is the expected fail-safe behaviour, not simulated vehicle data.
Release signing reads EV_KEYSTORE, EV_KEYSTORE_PASSWORD, EV_KEY_ALIAS and
EV_KEY_PASSWORD, or their local gradle.properties equivalents. Never commit credentials.
app/src/main/— driver dashboard, lifecycle, presentation and diagnostics.app/src/main/res/— EVSuite driver interface.EVHardware/— shared vehicle abstraction, telemetry model, trip maths and storage.
- DESIGN.md — normative EVSuite interface rules.
- SECURITY.md — capability boundary and disclosure.
- CONTRIBUTING.md — development expectations.
- DISCLAIMER.md — vehicle-safety disclaimer.
- CHANGELOG.md — release history.
The application has no network, location, overlay, installer or vehicle-write capability. Permission drift is blocked in CI. Report vulnerabilities according to SECURITY.md.
See CONTRIBUTING.md. Vehicle-facing changes require nullable failure paths, JVM tests for decisions, and on-vehicle confirmation before release.
MIT licensed. Not affiliated with, endorsed by or supported by SAIC Motor or MG Motor.

