App 2.13.0: tyre pressures in bar; 5-minute average power

Tyre pressures show in bar by default; Settings → Display offers kPa
and psi as well. Display only: the car reports kPa and the server keeps
storing kPa.

A "Power, 5-min average" card under Power: the time-weighted mean
battery power over the last five minutes, standing included, from the
same samples as the 5-minute range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
This commit is contained in:
2026-10-18 13:26:02 +02:00
co-authored by Claude Opus 5.5
parent 66fed48aae
commit 40906ec4a7
12 changed files with 159 additions and 8 deletions
@@ -93,7 +93,7 @@ public class MainActivity extends AppCompatActivity {
vehTireFl, vehTireFr, vehTireRl, vehTireRr,
vehRangeTrip, vehRangeTripNote, vehRangeAverage, vehRangeAverageNote,
vehUsageTrip, vehUsageTripNote, vehUsageAverage, vehUsageAverageNote,
vehEnergyTrip, vehEnergyTripNote;
vehEnergyTrip, vehEnergyTripNote, vehPowerAverage, vehPowerAverageNote;
/** Usable pack capacity for the range estimates; the car does not publish it. */
static final String USABLE_KWH_KEY = "usable_kwh";
@@ -977,6 +977,7 @@ public class MainActivity extends AppCompatActivity {
voiceKeySwitch.setChecked(UploadSettings.voiceKeyOpensApp(prefs));
voiceKeySwitch.setOnCheckedChangeListener((btn, checked) ->
prefs.edit().putBoolean(UploadSettings.KEY_VOICE_KEY_OPENS, checked).apply());
bindTireUnit();
fullScreenSwitch = settingsPane.findViewById(R.id.full_screen_switch);
fullScreenSwitch.setChecked(UploadSettings.fullScreen(prefs));
fullScreenSwitch.setOnCheckedChangeListener((btn, checked) -> {
@@ -1057,6 +1058,26 @@ public class MainActivity extends AppCompatActivity {
}, "abrp-test").start();
}
/** Tyre pressure unit: display only, read on every refresh of the Overview. */
private void bindTireUnit() {
android.widget.Spinner spinner = settingsPane.findViewById(R.id.tire_unit_spinner);
PressureUnit[] units = PressureUnit.values();
String[] labels = new String[units.length];
for (int i = 0; i < units.length; i++) labels[i] = units[i].label;
android.widget.ArrayAdapter<String> adapter = new android.widget.ArrayAdapter<>(
this, R.layout.spinner_value, labels);
adapter.setDropDownViewResource(R.layout.spinner_dropdown);
spinner.setAdapter(adapter);
spinner.setSelection(PressureUnit.fromPref(prefs.getString(PressureUnit.PREF_KEY, null)).ordinal());
spinner.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(android.widget.AdapterView<?> parent, View view, int position, long id) {
prefs.edit().putString(PressureUnit.PREF_KEY, units[position].name()).apply();
}
@Override public void onNothingSelected(android.widget.AdapterView<?> parent) { }
});
}
/** The service reads these settings on every tick, so a change applies without a restart. */
private void bindCadenceControls() {
UploadSettings current = UploadSettings.from(prefs);
@@ -1190,6 +1211,8 @@ public class MainActivity extends AppCompatActivity {
vehUsageAverageNote = vehiclePane.findViewById(R.id.vehicle_usage_average_note);
vehEnergyTrip = vehiclePane.findViewById(R.id.vehicle_energy_trip);
vehEnergyTripNote = vehiclePane.findViewById(R.id.vehicle_energy_trip_note);
vehPowerAverage = vehiclePane.findViewById(R.id.vehicle_power_average);
vehPowerAverageNote = vehiclePane.findViewById(R.id.vehicle_power_average_note);
}
private double usableKwh() {
@@ -1207,6 +1230,9 @@ public class MainActivity extends AppCompatActivity {
estimator.add(monotonicMs, s.getBatteryPowerKw(), s.getSpeedKmh());
Double remaining = RangeEstimator.remainingKwh(s.getSocPercent(), usableKwh());
RangeEstimator.Estimate trip = estimator.sinceStart(remaining);
Double power = estimator.averagePowerKw(monotonicMs);
vehPowerAverage.setText(power == null ? "—" : getString(R.string.power_kw, power));
vehPowerAverageNote.setText(power == null ? R.string.power_waiting : R.string.usage_last_5_min);
Double energy = estimator.energySinceStart();
vehEnergyTrip.setText(energy == null ? "—" : getString(R.string.energy_kwh, energy));
vehEnergyTripNote.setText(energy == null ? R.string.energy_trip_waiting : R.string.energy_trip_note);
@@ -1264,10 +1290,11 @@ public class MainActivity extends AppCompatActivity {
vehCharging.setText(chargingLabel(s));
refreshRangeEstimates(s);
vehTireFl.setText(fmt(s.getTirePressures().getFrontLeftKpa(), "%.0f kPa"));
vehTireFr.setText(fmt(s.getTirePressures().getFrontRightKpa(), "%.0f kPa"));
vehTireRl.setText(fmt(s.getTirePressures().getRearLeftKpa(), "%.0f kPa"));
vehTireRr.setText(fmt(s.getTirePressures().getRearRightKpa(), "%.0f kPa"));
PressureUnit unit = PressureUnit.fromPref(prefs.getString(PressureUnit.PREF_KEY, null));
vehTireFl.setText(unit.format(s.getTirePressures().getFrontLeftKpa()));
vehTireFr.setText(unit.format(s.getTirePressures().getFrontRightKpa()));
vehTireRl.setText(unit.format(s.getTirePressures().getRearLeftKpa()));
vehTireRr.setText(unit.format(s.getTirePressures().getRearRightKpa()));
} catch (Throwable ignored) {
// Leave the last good reading on screen.
}