A new Overview style: the Grid over the roads round the car from
OpenStreetMap, drawn in the floor's perspective, heading up, the bigger
roads glowing brighter, the car as a chevron.
Server: POST /v1/map/roads {z:14,x,y} fetches a tile's drivable roads
from Overpass (OVERPASS_URL; one request at a time, at least a second
apart), simplifies them to tile-local points in four classes, caches
them for 30 days and never logs the tile.
App: MapRoads keeps the 3x3 tiles round the car from its own cache or
the server; GPS only while the style is shown; bearing from the GPS or
from successive positions. Without GPS, server or roads the plain floor
says why. OSM attribution on screen and in LICENSE.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
The owner lifted the read-only rule for the drive mode alone. Settings
has Eco, Normal, Sport, Snow and Custom; the lit button is what the car
reports. A tap reads gear and speed fresh and writes only in P at 0 km/h
(DriveModeWrite, unit-tested; unreadable is a refusal), through a CPM-only
write behind EVHardware's standstill gate, then reads the mode back and
says what the car reports. The wide layout's charging price joined the
battery card so the page still fits. Not tried on the car.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
The 2.32.0 recording (ACC set to 101, 90 and 80 km/h behind another car)
found none of it among 1,194 values: the head unit does not get the ACC
data. Removed the cruise log and the set-speed read (EVHardware is as
before 2.27.3); the finding is under "Signals the car does not provide".
The recorder stays as the Signal recorder, for finding other signals.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
The 2.27.3 log wrote a line only when the target speed changed, so the
car showed one line at the start. Now a line is written on any change of
a mode or the target and every 2 s while driving, with the raw
driver-assistance properties (target speed, assist and speed-assist
modes, the followed object) and the reason for any unread value. The
last 600 lines are kept in an appended file; the Logs tab shows 150.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
The head unit names a vendor float AAD_EPTCCTRGTSPD (0x2160A15B),
the cruise control target speed by its name. EVHardware reads it raw;
the Logs tab lists each change with time, speed and gear, to establish
the unit and the off value on the car. Emulator only (absent there).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
The badge said "D" for every gear that was not P, so N and R read as D.
EVHardware now passes on the raw gear code; the badge shows P for 1,
no letter for codes not yet mapped, "—" when unread. The Logs tab lists
each change of the code with time and speed, to match R, N and D on
the car. Emulator only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
Three-way merge from b595ccb, the commit Fatih copied, to upstream's
current state; Fatih's vendor reads (tyres, mileage, charge status,
SWI69) stay. LICENSE.md records the base for the next update.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
EVHardware's notes call the licence of EVProfile's upstream unresolved.
Checked: malys/EVProfile is MIT, forked from SliDeeN/MG4Control and last
merged from it on 2026-08-02. MG4Control is MIT up to 2.6.5
(2026-08-05) and GPL v3 from 2.6.6 (2026-09-02), with the earlier
versions staying MIT, so the code EVProfile took is from the MIT
period. Recorded with links; not an audit of every EVHardware line.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
Leon Kernan's ABRP_Uploader has carried the MIT Licence since
2026-07-29 (lkernan/ABRP_Uploader commit 75d8f2bc), so the inherited
"no licence upstream, status unresolved" notes no longer hold.
- LICENSE: MIT, now naming every copyright holder in the fork chain
(Leon Kernan, EVABRPUploader contributors, FatihsMG4 contributors,
Nils Stinnesbeck).
- LICENSE.md: rewritten. The repository is MIT except EVHardware/,
which is PolyForm Noncommercial 1.0.0; the app links it into the APK,
so the built app is non-commercial. EVHardware's own caveat about
EVProfile stays with it.
- README, AGENTS.md, CONTRIBUTING.md and SPECS.md say the same.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
A fork of malys/EVABRPUploader (itself a fork of Leon Kernan's ABRP_Uploader)
carrying the changes that make it work on this car. History starts here: the
tree is what matters, and the upstream projects are where the earlier work
belongs.
EVHardware is vendored rather than tracked as a submodule, so one clone
builds.
Telemetry. SOC, battery power and range read as unavailable on SWI69 because
the vendor fallbacks were gated to SWI68 alone, while the property ids they
use are the ones this car publishes — the gates now admit SWI69. Tyre
pressure, the odometer and charge status come from the vendor block too,
since the generic properties for all three are declared here and never
publish. Tyre pressure is confirmed on the vehicle; the other two are not
yet.
Vehicle page. Every signal the car answers, in a table. One that it does not
publish shows a dash: an unimplemented VHAL property returns zero, and
"0 °C" would read as a measurement.
Wi-Fi page. Joins a network the unit already has saved, so a phone hotspot
does not need a trip into Settings on every drive. Tried on the upload tick
and from a button, skipped while already associated. This leans on the unit
being API 28 and the build being platform-signed — getConfiguredNetworks and
enableNetwork are closed to ordinary apps from API 29 — and fails quietly
where that does not hold.
The OTA updater points at this repository. An APK from upstream is signed
with a different key, which Android will not install over a platform-signed
build.
Co-Authored-By: Claude <noreply@anthropic.com>