App 2.22.3: rename the Overview style Dashboard to Gauges

The stored value becomes GAUGES; DASHBOARD still selects it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
2026-10-24 19:25:09 +02:00
co-authored by Claude Opus 5.5
parent c6643e7df2
commit c649ff6e28
9 changed files with 33 additions and 28 deletions
+1 -1
View File
@@ -69,7 +69,7 @@ Repository: `ssh://git@git.stinnesbeck.com:2222/nils/mg4.git` (remote `origin`),
| Tab | Contents | | Tab | Contents |
|---|---| |---|---|
| Overview | value tiles (battery, range, range/usage/energy since start, 5-min averages of range, usage, power, speed), vehicle info (odometer, lease allowance and the odometer against it), tyre pressures; read every 0.5 s on a background thread. Three styles (Settings → Overview style): Tiles, Dashboard (`GaugeView` needles), Cockpit (`RingView` rings, `TraceView` power trace) | | Overview | value tiles (battery, range, range/usage/energy since start, 5-min averages of range, usage, power, speed), vehicle info (odometer, lease allowance and the odometer against it), tyre pressures; read every 0.5 s on a background thread. Three styles (Settings → Overview style): Tiles, Gauges (`GaugeView` needles), Cockpit (`RingView` rings, `TraceView` power trace) |
| Consumption / Charging | period totals, daily log, charging sessions and curve | | Consumption / Charging | period totals, daily log, charging sessions and curve |
| Live data | on/off, ABRP API key and user token, upload frequency | | Live data | on/off, ABRP API key and user token, upload frequency |
| Server | URL, pairing by QR, ingest token, installation ID (read-only), config import | | Server | URL, pairing by QR, ingest token, installation ID (read-only), config import |
+4
View File
@@ -131,6 +131,10 @@ tyre pressures, GPS (lat, lon, elevation, heading) and the is_* flags. It does *
confirmed car facts, app structure, UI conventions, build/test/ship, documents. It replaces confirmed car facts, app structure, UI conventions, build/test/ship, documents. It replaces
upstream's EVABRPUploader text. The test emulator is now in the flake: `nix run .#car-emulator` upstream's EVABRPUploader text. The test emulator is now in the flake: `nix run .#car-emulator`
(Android 9 AOSP at 1920×720, 160 dpi; the car build installs as the system user — checked). (Android 9 AOSP at 1920×720, 160 dpi; the car build installs as the system user — checked).
- 2026-10-24 — App 2.22.3: the Overview style "Dashboard" is now called "Gauges" (stored as
`GAUGES`; the old value `DASHBOARD` still selects it, so the choice survives the update;
`pane_dashboard.xml` is `pane_gauges.xml`). The branches `dashboard-gauges` and
`dashboard-cockpit`, merged into main, are deleted. Tests and lint.
- 2026-10-24 — App 2.22.2 (branch `dashboard-cockpit`): the gear badge names all four gears. - 2026-10-24 — App 2.22.2 (branch `dashboard-cockpit`): the gear badge names all four gears.
The owner shifted through the lever with 2.22.1 and read the codes off the Logs tab: 1 P, The owner shifted through the lever with 2.22.1 and read the codes off the Logs tab: 1 P,
2 R, 3 N, 4 D (firmware SWI68-29958-1300R69). `Gear.label` maps them (unit-tested); any 2 R, 3 N, 4 D (firmware SWI68-29958-1300R69). `Gear.label` maps them (unit-tested); any
+2 -2
View File
@@ -34,8 +34,8 @@ android {
applicationId "com.stinnesbeck.nilsmg4" applicationId "com.stinnesbeck.nilsmg4"
minSdk 27 minSdk 27
targetSdk 36 targetSdk 36
versionCode 113 versionCode 114
versionName "2.22.2" versionName "2.22.3"
// Nothing about the server ships in the APK: its URL and ingest token are entered in // Nothing about the server ships in the APK: its URL and ingest token are entered in
// the app's Server tab (ServerConfig), and the database is only reachable by the server. // the app's Server tab (ServerConfig), and the database is only reachable by the server.
@@ -8,7 +8,7 @@ import android.util.AttributeSet;
import android.view.View; import android.view.View;
/** /**
* The dashboard strip's battery: an outline with a terminal and vertical cells filled to the * The Gauges strip's battery: an outline with a terminal and vertical cells filled to the
* state of charge, in the accent colour. Null draws the empty outline, never an empty battery. * state of charge, in the accent colour. Null draws the empty outline, never an empty battery.
*/ */
public final class BatteryBarView extends View { public final class BatteryBarView extends View {
@@ -10,7 +10,7 @@ import android.view.View;
import java.util.Locale; import java.util.Locale;
/** /**
* A round instrument for the dashboard Overview: a 240° scale open at the bottom, major and minor * A round instrument for the Gauges Overview: a 240° scale open at the bottom, major and minor
* ticks, numbers, a needle, and up to three lines of text in the middle — the unit, the value as * ticks, numbers, a needle, and up to three lines of text in the middle — the unit, the value as
* digits, and a caption. * digits, and a caption.
* *
+1 -1
View File
@@ -1,7 +1,7 @@
package com.evsuite.abrp; package com.evsuite.abrp;
/** /**
* The gear letter for the dashboards, from the car's raw gear code: 1 P, 2 R, 3 N, 4 D, read * The gear letter for the Overview styles, from the car's raw gear code: 1 P, 2 R, 3 N, 4 D, read
* on the owner's car (firmware SWI68-29958-1300R69) by shifting through the lever. Any other * on the owner's car (firmware SWI68-29958-1300R69) by shifting through the lever. Any other
* code shows no letter rather than a guess; unread is "—". * code shows no letter rather than a guess; unread is "—".
*/ */
@@ -66,7 +66,7 @@ public class MainActivity extends AppCompatActivity {
private View serverPane; private View serverPane;
private View logPane; private View logPane;
private View vehiclePane; private View vehiclePane;
private View dashboardPane; private View gaugesPane;
private View cockpitPane; private View cockpitPane;
private View consumptionPane; private View consumptionPane;
private View chargingPane; private View chargingPane;
@@ -244,7 +244,7 @@ public class MainActivity extends AppCompatActivity {
servicePane = inflatePane(R.layout.pane_service); servicePane = inflatePane(R.layout.pane_service);
serverPane = inflatePane(R.layout.pane_server); serverPane = inflatePane(R.layout.pane_server);
vehiclePane = inflatePane(R.layout.pane_vehicle); vehiclePane = inflatePane(R.layout.pane_vehicle);
dashboardPane = inflatePane(R.layout.pane_dashboard); gaugesPane = inflatePane(R.layout.pane_gauges);
cockpitPane = inflatePane(R.layout.pane_cockpit); cockpitPane = inflatePane(R.layout.pane_cockpit);
// The Overview page holds both styles; Settings → Overview style picks the one shown. // The Overview page holds both styles; Settings → Overview style picks the one shown.
android.widget.FrameLayout overviewPage = new android.widget.FrameLayout(this); android.widget.FrameLayout overviewPage = new android.widget.FrameLayout(this);
@@ -252,7 +252,7 @@ public class MainActivity extends AppCompatActivity {
android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.MATCH_PARENT)); android.view.ViewGroup.LayoutParams.MATCH_PARENT));
overviewPage.addView(vehiclePane); overviewPage.addView(vehiclePane);
overviewPage.addView(dashboardPane); overviewPage.addView(gaugesPane);
overviewPage.addView(cockpitPane); overviewPage.addView(cockpitPane);
consumptionPane = inflatePane(R.layout.pane_consumption); consumptionPane = inflatePane(R.layout.pane_consumption);
chargingPane = inflatePane(R.layout.pane_charging); chargingPane = inflatePane(R.layout.pane_charging);
@@ -263,7 +263,7 @@ public class MainActivity extends AppCompatActivity {
UpdateLog.noteVersion(this, BuildConfig.VERSION_NAME); UpdateLog.noteVersion(this, BuildConfig.VERSION_NAME);
bindVehiclePane(); bindVehiclePane();
bindDashboard(); bindGauges();
bindCockpit(); bindCockpit();
bindConsumptionPane(); bindConsumptionPane();
bindChargingPane(); bindChargingPane();
@@ -1424,7 +1424,7 @@ public class MainActivity extends AppCompatActivity {
} }
} }
// ---------- Dashboard (Overview style) ---------- // ---------- Gauges (Overview style) ----------
static final String PREF_OVERVIEW_STYLE = "overview_style"; static final String PREF_OVERVIEW_STYLE = "overview_style";
private GaugeView dashPower, dashSpeed, dashBattery; private GaugeView dashPower, dashSpeed, dashBattery;
@@ -1434,11 +1434,12 @@ public class MainActivity extends AppCompatActivity {
private Double dashTripKm; private Double dashTripKm;
/** The stored values of the Overview styles, in the order of the drop-down. */ /** The stored values of the Overview styles, in the order of the drop-down. */
private static final String[] OVERVIEW_STYLES = { "TILES", "DASHBOARD", "COCKPIT" }; private static final String[] OVERVIEW_STYLES = { "TILES", "GAUGES", "COCKPIT" };
/** The chosen style's index in {@link #OVERVIEW_STYLES}; anything unknown is Tiles. */ /** The chosen style's index in {@link #OVERVIEW_STYLES}; anything unknown is Tiles. */
private int overviewStyle() { private int overviewStyle() {
String style = prefs.getString(PREF_OVERVIEW_STYLE, "TILES"); String style = prefs.getString(PREF_OVERVIEW_STYLE, "TILES");
if ("DASHBOARD".equals(style)) style = "GAUGES"; // its name before 2.22.3
for (int i = 0; i < OVERVIEW_STYLES.length; i++) if (OVERVIEW_STYLES[i].equals(style)) return i; for (int i = 0; i < OVERVIEW_STYLES.length; i++) if (OVERVIEW_STYLES[i].equals(style)) return i;
return 0; return 0;
} }
@@ -1446,13 +1447,13 @@ public class MainActivity extends AppCompatActivity {
private void applyOverviewStyle() { private void applyOverviewStyle() {
int style = overviewStyle(); int style = overviewStyle();
vehiclePane.setVisibility(style == 0 ? View.VISIBLE : View.GONE); vehiclePane.setVisibility(style == 0 ? View.VISIBLE : View.GONE);
dashboardPane.setVisibility(style == 1 ? View.VISIBLE : View.GONE); gaugesPane.setVisibility(style == 1 ? View.VISIBLE : View.GONE);
cockpitPane.setVisibility(style == 2 ? View.VISIBLE : View.GONE); cockpitPane.setVisibility(style == 2 ? View.VISIBLE : View.GONE);
} }
/** Tiles (the cards), Dashboard (gauges) or Cockpit (rings); all are fed on every reading. */ /** Tiles (the cards), Gauges (needles) or Cockpit (rings); all are fed on every reading. */
private void bindOverviewStyle() { private void bindOverviewStyle() {
String[] labels = { getString(R.string.overview_style_tiles), getString(R.string.overview_style_dashboard), String[] labels = { getString(R.string.overview_style_tiles), getString(R.string.overview_style_gauges),
getString(R.string.overview_style_cockpit) }; getString(R.string.overview_style_cockpit) };
bindChoices(settingsPane.findViewById(R.id.overview_style_choices), labels, overviewStyle(), bindChoices(settingsPane.findViewById(R.id.overview_style_choices), labels, overviewStyle(),
position -> { position -> {
@@ -1461,15 +1462,15 @@ public class MainActivity extends AppCompatActivity {
}); });
} }
private void bindDashboard() { private void bindGauges() {
dashPower = dashboardPane.findViewById(R.id.dash_power); dashPower = gaugesPane.findViewById(R.id.dash_power);
dashSpeed = dashboardPane.findViewById(R.id.dash_speed); dashSpeed = gaugesPane.findViewById(R.id.dash_speed);
dashBattery = dashboardPane.findViewById(R.id.dash_battery); dashBattery = gaugesPane.findViewById(R.id.dash_battery);
dashBatteryBar = dashboardPane.findViewById(R.id.dash_battery_bar); dashBatteryBar = gaugesPane.findViewById(R.id.dash_battery_bar);
dashGear = dashboardPane.findViewById(R.id.dash_gear); dashGear = gaugesPane.findViewById(R.id.dash_gear);
dashClimate = dashboardPane.findViewById(R.id.dash_climate); dashClimate = gaugesPane.findViewById(R.id.dash_climate);
dashUsage = dashboardPane.findViewById(R.id.dash_usage); dashUsage = gaugesPane.findViewById(R.id.dash_usage);
dashBatteryText = dashboardPane.findViewById(R.id.dash_battery_text); dashBatteryText = gaugesPane.findViewById(R.id.dash_battery_text);
dashPower.configure(-50f, 150f, 50f, 5, getString(R.string.dash_unit_kw)); dashPower.configure(-50f, 150f, 50f, 5, getString(R.string.dash_unit_kw));
dashSpeed.configure(0f, 180f, 20f, 4, getString(R.string.dash_unit_kmh)); dashSpeed.configure(0f, 180f, 20f, 4, getString(R.string.dash_unit_kmh));
dashBattery.configure(0f, 100f, 25f, 5, getString(R.string.dash_unit_battery)); dashBattery.configure(0f, 100f, 25f, 5, getString(R.string.dash_unit_battery));
@@ -1538,7 +1539,7 @@ public class MainActivity extends AppCompatActivity {
} }
/** The gauges and the strip; every value null-safe ("—", no needle). */ /** The gauges and the strip; every value null-safe ("—", no needle). */
private void showDashboard(EnergySnapshot s) { private void showGauges(EnergySnapshot s) {
if (dashPower == null) return; if (dashPower == null) return;
Float power = s.getBatteryPowerKw(); Float power = s.getBatteryPowerKw();
dashPower.setValue(power, power == null ? null : String.format(java.util.Locale.US, "%.1f", power), null); dashPower.setValue(power, power == null ? null : String.format(java.util.Locale.US, "%.1f", power), null);
@@ -1575,7 +1576,7 @@ public class MainActivity extends AppCompatActivity {
vehTireFr.setText(unit.format(s.getTirePressures().getFrontRightKpa())); vehTireFr.setText(unit.format(s.getTirePressures().getFrontRightKpa()));
vehTireRl.setText(unit.format(s.getTirePressures().getRearLeftKpa())); vehTireRl.setText(unit.format(s.getTirePressures().getRearLeftKpa()));
vehTireRr.setText(unit.format(s.getTirePressures().getRearRightKpa())); vehTireRr.setText(unit.format(s.getTirePressures().getRearRightKpa()));
showDashboard(s); showGauges(s);
showCockpit(s); showCockpit(s);
} catch (Throwable ignored) { } catch (Throwable ignored) {
// Leave the last good reading on screen. // Leave the last good reading on screen.
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- The Overview as an instrument cluster (Settings → Overview style → Dashboard): power, speed <!-- The Overview as an instrument cluster (Settings → Overview style → Gauges): power, speed
and battery as gauges, and a strip of gear, climate, clock, usage and battery below. --> and battery as gauges, and a strip of gear, climate, clock, usage and battery below. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingStart="24dp" android:paddingEnd="24dp" android:paddingTop="8dp" android:paddingBottom="12dp"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingStart="24dp" android:paddingEnd="24dp" android:paddingTop="8dp" android:paddingBottom="12dp">
<LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:gravity="bottom" android:baselineAligned="false"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:gravity="bottom" android:baselineAligned="false">
+1 -1
View File
@@ -121,7 +121,7 @@
<string name="hint_full_screen">Hides the car\'s top and bottom bars while this app is open. Swipe in from the top or bottom edge to show them briefly, e.g. for the climate controls.</string> <string name="hint_full_screen">Hides the car\'s top and bottom bars while this app is open. Swipe in from the top or bottom edge to show them briefly, e.g. for the climate controls.</string>
<string name="label_overview_style">Overview style</string> <string name="label_overview_style">Overview style</string>
<string name="overview_style_tiles">Tiles</string> <string name="overview_style_tiles">Tiles</string>
<string name="overview_style_dashboard">Dashboard</string> <string name="overview_style_gauges">Gauges</string>
<string name="dash_unit_kw">kW</string> <string name="dash_unit_kw">kW</string>
<string name="dash_unit_kmh">km/h</string> <string name="dash_unit_kmh">km/h</string>
<string name="dash_unit_battery">SOC</string> <string name="dash_unit_battery">SOC</string>