You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 01863e7
Browse filesBrowse the repository at this point in the historyBrowse files
Add Unstable badge, include_prereleases on Release badge, warning callout,
suite section, Part-of-EVSuite and contents; Layout moved under Building;
documents as table. Fix scrambled paragraphs in How it works / Configuration
and a wrong MIT mention (licence is PolyForm Noncommercial).
analysis/CP-040: drop decompiled-sources/apks wording.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EVChargePilot is an EVSuite application for Android Automotive OS 9. It reads typed,
@@ -40,42 +68,6 @@ diagnostic screen works with no network at all; the route planner is the one fea
40
68
uses one, with a key the driver supplies, and it carries a route and never vehicle data
41
69
(see [SECURITY.md](SECURITY.md) and `analysis/CP-043_network_and_location.md`).
42
70
43
-
## Features
44
-
45
-
- Vehicle-reported SOC and range.
46
-
- A grouped thermal/climate state block: outside, cabin and evidence-gated battery
47
-
temperatures; HVAC, AC, auto, econ and recirculation states; fan level/maximum; and
48
-
driver/passenger targets when each signal is available.
49
-
- Automatic trip detection plus parked-only manual controls and configuration.
50
-
- Distance and duration calculated locally.
51
-
- Evidence-gated signed battery power with a static traction/regeneration scale.
52
-
- Pack temperature and charging state when exposed by the current firmware.
53
-
- Energy and regeneration integration from the shared EVHardware power convention.
54
-
- Parked-only, bounded diagnostic/evidence ZIP to an explicitly chosen removable USB volume.
55
-
- Atomic, app-private trip history and in-app crash diagnostics.
56
-
- Charge on arrival from the head unit's own guidance, with no network and no key.
57
-
- A parked-only charging-stop plan: type a destination, and the app answers whether the trip
58
-
needs a charging stop and in how many kilometres. It needs an OpenRouteService key you supply
59
-
(see [Configuration](#configuration)); without one, every other screen still works.
60
-
- On that same plan: what slowing down would change. Where the road ahead is fast, the app
61
-
shows what 130, 120, 110, 100 and 90 km/h would save in charge and cost in minutes, and
62
-
names the mildest slowdown that removes the charging stop. A second road comes back with the
63
-
same request and is compared on distance, time and charge. It never recommends a speed.
64
-
- A battery page: the pack's state of health measured rather than declared, how long since its
65
-
charge gauge last had a full charge to anchor itself on, what the pack has been subjected to,
66
-
and what the last charge cost — points gained, duration, and approximate energy and mean power
67
-
where this app watched the whole session. Read-only, like every other screen: no charge limit,
68
-
no schedule, no preheat.
69
-
70
-
Every signal remains best-effort: unsupported or unreadable properties are displayed as `—`,
71
-
never zero. Charger data and energy-source attribution remain outside this initial milestone.
72
-
73
-
## Requirements
74
-
75
-
- SAIC MG4 head unit running Android Automotive OS 9 or a compatible test device.
76
-
- Android API 28 or newer.
77
-
- Platform signing for privileged car-property permissions where required by the firmware.
78
-
79
71
## How it works
80
72
81
73
EVHardware's `EnergyTelemetryReader` produces one coherent nullable snapshot per second.
@@ -103,12 +95,10 @@ unique temporary file and atomic rename.
103
95
Automatic detection is enabled by default. A foreground service owns the sampler so detection
104
96
and recording continue when the driver opens another app. On firmware where speed stays
105
97
unavailable, ten consecutive misses suspend idle background polling; opening the dashboard
106
-
performs a bounded retry. Active trips remain fail-closed and under manual control. The unstable
107
-
The unstable build keeps every automatically detected trip with a positive trustworthy
98
+
performs a bounded retry. Active trips remain fail-closed and under manual control. The unstable build keeps every automatically detected trip with a positive trustworthy
108
99
distance. The shared store still caps history at 200 trips and 2 MiB, discarding oldest
109
100
sample tracks before oldest summaries. Each successful save refreshes the local model.
110
-
Manual recordings are always kept.
111
-
trip's reported duration is the time actually covered by usable samples, not wall clock: a suspended
101
+
Manual recordings are always kept. A trip's reported duration is the time actually covered by usable samples, not wall clock: a suspended
112
102
sampler adds nothing to duration, distance or energy, so consumption averages compare values
113
103
measured over the same interval.
114
104
@@ -123,6 +113,42 @@ fresh readable speed at or below 0.1 km/h, runs off the main thread, caps the te
123
113
128 KiB, each evidence file at 64 KiB and the ZIP at 768 KiB, then atomically renames a synced
124
114
temporary file on USB. No archive copy accumulates on AAOS.
125
115
116
+
## Requirements
117
+
118
+
- SAIC MG4 head unit running Android Automotive OS 9 or a compatible test device.
119
+
- Android API 28 or newer.
120
+
- Platform signing for privileged car-property permissions where required by the firmware.
121
+
122
+
## Features
123
+
124
+
- Vehicle-reported SOC and range.
125
+
- A grouped thermal/climate state block: outside, cabin and evidence-gated battery
126
+
temperatures; HVAC, AC, auto, econ and recirculation states; fan level/maximum; and
127
+
driver/passenger targets when each signal is available.
128
+
- Automatic trip detection plus parked-only manual controls and configuration.
129
+
- Distance and duration calculated locally.
130
+
- Evidence-gated signed battery power with a static traction/regeneration scale.
131
+
- Pack temperature and charging state when exposed by the current firmware.
132
+
- Energy and regeneration integration from the shared EVHardware power convention.
133
+
- Parked-only, bounded diagnostic/evidence ZIP to an explicitly chosen removable USB volume.
134
+
- Atomic, app-private trip history and in-app crash diagnostics.
135
+
- Charge on arrival from the head unit's own guidance, with no network and no key.
136
+
- A parked-only charging-stop plan: type a destination, and the app answers whether the trip
137
+
needs a charging stop and in how many kilometres. It needs an OpenRouteService key you supply
138
+
(see [Configuration](#configuration)); without one, every other screen still works.
139
+
- On that same plan: what slowing down would change. Where the road ahead is fast, the app
140
+
shows what 130, 120, 110, 100 and 90 km/h would save in charge and cost in minutes, and
141
+
names the mildest slowdown that removes the charging stop. A second road comes back with the
142
+
same request and is compared on distance, time and charge. It never recommends a speed.
143
+
- A battery page: the pack's state of health measured rather than declared, how long since its
144
+
charge gauge last had a full charge to anchor itself on, what the pack has been subjected to,
145
+
and what the last charge cost — points gained, duration, and approximate energy and mean power
146
+
where this app watched the whole session. Read-only, like every other screen: no charge limit,
147
+
no schedule, no preheat.
148
+
149
+
Every signal remains best-effort: unsupported or unreadable properties are displayed as `—`,
150
+
never zero. Charger data and energy-source attribution remain outside this initial milestone.
151
+
126
152
## Trip export formats
127
153
128
154
The trip history can export one trip or the full bounded ledger without network or storage
@@ -148,19 +174,14 @@ readings are likewise explicit `null`.
148
174
Both formats are limited to the history ceiling of 200 trips and 2 MiB per export. The export
149
175
directory retains the eight newest generated files so repeated exports cannot grow without bound.
150
176
151
-
## Install
152
-
153
-
Install only a signed APK you trust, while the vehicle is parked. Stable releases do not
154
-
self-update.
155
-
156
177
## Configuration
157
178
158
179
Automatic trip detection is enabled by default. Its switch, and the manual start/stop action,
180
+
can be changed only while the vehicle reports zero speed. If speed is unavailable, the controls
181
+
fail closed and the dashboard explains why.
159
182
160
183
Unstable shows the live eco-advice line by default so a fresh install starts learning without a
161
184
setup step. Stable keeps that line opt-in. Spoken advice remains opt-in in both channels.
162
-
can be changed only while the vehicle reports zero speed. If speed is unavailable, the controls
163
-
fail closed and the dashboard explains why.
164
185
165
186
### Routing key
166
187
@@ -240,9 +261,14 @@ Charger records are shown with their data provider and the date the record was l
240
261
because a charger dataset is out of date the day it is published and hiding that turns a
241
262
suggestion into a promise. User-contributed Open Charge Map data is CC BY 4.0; imported records
242
263
keep their original provider's licence, which is why the provider is named on screen next to
243
-
each charger. Both licences permit use in this MIT-licensed app as long as the attribution is
264
+
each charger. Both licences permit use in this app as long as the attribution is
244
265
displayed, and it is.
245
266
267
+
## Install
268
+
269
+
Install only a signed APK you trust, while the vehicle is parked. Stable releases do not
270
+
self-update.
271
+
246
272
## Building
247
273
248
274
With [mise](https://mise.jdx.dev/):
@@ -254,6 +280,12 @@ mise run test
254
280
mise run build
255
281
```
256
282
283
+
### Layout
284
+
285
+
-`app/src/main/` — driver dashboard, lifecycle, presentation and diagnostics.
0 commit comments