diff --git a/EVHardware/lib/src/main/java/com/evsuite/hardware/VehicleSpeedScale.kt b/EVHardware/lib/src/main/java/com/evsuite/hardware/VehicleSpeedScale.kt index 189d28d..4103af0 100644 --- a/EVHardware/lib/src/main/java/com/evsuite/hardware/VehicleSpeedScale.kt +++ b/EVHardware/lib/src/main/java/com/evsuite/hardware/VehicleSpeedScale.kt @@ -28,7 +28,7 @@ object VehicleSpeedScale { * route of known length, both over by the same 3.5x, with the adapter odometer as the * independent reference. Add a generation here only with the same kind of evidence. */ - private val REPORTS_KMH = setOf(FirmwareInfo.Gen.SWI68) + private val REPORTS_KMH = setOf(FirmwareInfo.Gen.SWI68, FirmwareInfo.Gen.SWI69) /** True when this generation needs no conversion at all. */ fun reportsKmh(generation: FirmwareInfo.Gen): Boolean = generation in REPORTS_KMH diff --git a/EVHardware/lib/src/test/java/com/evsuite/hardware/VehicleSpeedScaleTest.kt b/EVHardware/lib/src/test/java/com/evsuite/hardware/VehicleSpeedScaleTest.kt index 2bc00d6..2f059b3 100644 --- a/EVHardware/lib/src/test/java/com/evsuite/hardware/VehicleSpeedScaleTest.kt +++ b/EVHardware/lib/src/test/java/com/evsuite/hardware/VehicleSpeedScaleTest.kt @@ -7,14 +7,16 @@ import org.junit.Test class VehicleSpeedScaleTest { - @Test fun `SWI68 reports km per hour and is not converted again`() { + @Test fun `SWI68 and SWI69 report km per hour and are not converted again`() { assertTrue(VehicleSpeedScale.reportsKmh(FirmwareInfo.Gen.SWI68)) + assertTrue(VehicleSpeedScale.reportsKmh(FirmwareInfo.Gen.SWI69)) assertEquals(34.4f, VehicleSpeedScale.toKmh(34.4f, FirmwareInfo.Gen.SWI68), 0.001f) + assertEquals(34.4f, VehicleSpeedScale.toKmh(34.4f, FirmwareInfo.Gen.SWI69), 0.001f) } @Test fun `an unproven generation keeps the specified conversion`() { FirmwareInfo.Gen.entries - .filterNot { it == FirmwareInfo.Gen.SWI68 } + .filterNot { it == FirmwareInfo.Gen.SWI68 || it == FirmwareInfo.Gen.SWI69 } .forEach { generation -> assertFalse("$generation is not proven", VehicleSpeedScale.reportsKmh(generation)) assertEquals( @@ -28,7 +30,7 @@ class VehicleSpeedScaleTest { @Test fun `reverse is a speed, not a negative one`() { assertEquals(12.0f, VehicleSpeedScale.toKmh(-12.0f, FirmwareInfo.Gen.SWI68), 0.001f) - assertEquals(36.0f, VehicleSpeedScale.toKmh(-10.0f, FirmwareInfo.Gen.SWI69), 0.001f) + assertEquals(10.0f, VehicleSpeedScale.toKmh(-10.0f, FirmwareInfo.Gen.SWI69), 0.001f) } @Test fun `the drive that proved it now integrates to the route it followed`() { diff --git a/FatihsMG4-unstable-2.2.27.apk.sha256 b/FatihsMG4-unstable-2.2.27.apk.sha256 deleted file mode 100644 index f2966a9..0000000 --- a/FatihsMG4-unstable-2.2.27.apk.sha256 +++ /dev/null @@ -1 +0,0 @@ -792f5e63d35dd2ffcfd95cad7ad56728c6b74b6063822b17535328a7858341b5 FatihsMG4-unstable-2.2.27.apk diff --git a/FatihsMG4-unstable-2.2.28.apk.sha256 b/FatihsMG4-unstable-2.2.28.apk.sha256 new file mode 100644 index 0000000..ba4b6a1 --- /dev/null +++ b/FatihsMG4-unstable-2.2.28.apk.sha256 @@ -0,0 +1 @@ +ece663b82660062d032e99d927eebdbb97adbcdcfa35262953a668875f58a903 FatihsMG4-unstable-2.2.28.apk diff --git a/app/build.gradle b/app/build.gradle index eda523e..56c55ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,8 +34,8 @@ android { applicationId "com.evsuite.abrp" minSdk 27 targetSdk 36 - versionCode 44 - versionName "2.2.27" + versionCode 45 + versionName "2.2.28" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/evsuite/abrp/ConsumptionTracker.java b/app/src/main/java/com/evsuite/abrp/ConsumptionTracker.java index 3ac3008..7138816 100644 --- a/app/src/main/java/com/evsuite/abrp/ConsumptionTracker.java +++ b/app/src/main/java/com/evsuite/abrp/ConsumptionTracker.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.SharedPreferences; import com.evsuite.hardware.telemetry.EnergySnapshot; +import com.evsuite.hardware.FirmwareInfo; import java.time.LocalDate; @@ -37,6 +38,7 @@ final class ConsumptionTracker { } synchronized void sample(EnergySnapshot s) { + migrateSwi69DistanceScale(s.getFirmware()); long now = s.getTimestampMs(); if (lastMs > 0 && now > lastMs) { double hours = (now - lastMs) / 3_600_000d; @@ -129,6 +131,20 @@ final class ConsumptionTracker { pruneOldDays(); } + /** 2.2.27 and earlier multiplied SWI69's already-km/h speed by 3.6. Repair distance only. */ + private void migrateSwi69DistanceScale(FirmwareInfo.Gen firmware) { + if (firmware != FirmwareInfo.Gen.SWI69 || prefs.getBoolean("swi69_distance_v2", false)) return; + SharedPreferences.Editor editor = prefs.edit(); + for (java.util.Map.Entry entry : prefs.getAll().entrySet()) { + String key = entry.getKey(); + if (!key.endsWith("_km") || !(entry.getValue() instanceof Long)) continue; + double oldKm = Double.longBitsToDouble((Long) entry.getValue()); + editor.putLong(key, Double.doubleToRawLongBits(oldKm / 3.6d)); + } + editor.putBoolean("swi69_distance_v2", true).commit(); + lifetime = load("life"); tripA = load("a"); tripB = load("b"); + } + private Totals load(String key) { return new Totals(bits(key,"km"), bits(key,"kwh"), bits(key,"h"), bits(key,"soc")); } private double bits(String key, String field) { return Double.longBitsToDouble(prefs.getLong(key + "_" + field, 0L)); } private static void save(SharedPreferences.Editor e, String key, Totals t) {