refactor: simplify jt808 mileage state

This commit is contained in:
lingniu
2026-07-01 02:10:04 +08:00
parent 7081800b84
commit 18ebd6c84f
4 changed files with 8 additions and 20 deletions

View File

@@ -18,7 +18,6 @@ public final class Jt808DailyMileageState {
private Instant lastEventTime; private Instant lastEventTime;
private double firstTotalMileageKm = Double.NaN; private double firstTotalMileageKm = Double.NaN;
private double lastTotalMileageKm = Double.NaN; private double lastTotalMileageKm = Double.NaN;
private double odometerMileageKm;
private int acceptedPoints; private int acceptedPoints;
private int totalMileageSamples; private int totalMileageSamples;
private int outOfOrderPoints; private int outOfOrderPoints;
@@ -50,7 +49,6 @@ public final class Jt808DailyMileageState {
Instant lastEventTime, Instant lastEventTime,
double firstTotalMileageKm, double firstTotalMileageKm,
double lastTotalMileageKm, double lastTotalMileageKm,
double odometerMileageKm,
int acceptedPoints, int acceptedPoints,
int totalMileageSamples, int totalMileageSamples,
int outOfOrderPoints, int outOfOrderPoints,
@@ -60,7 +58,6 @@ public final class Jt808DailyMileageState {
state.lastEventTime = lastEventTime; state.lastEventTime = lastEventTime;
state.firstTotalMileageKm = firstTotalMileageKm; state.firstTotalMileageKm = firstTotalMileageKm;
state.lastTotalMileageKm = lastTotalMileageKm; state.lastTotalMileageKm = lastTotalMileageKm;
state.odometerMileageKm = odometerMileageKm;
state.acceptedPoints = acceptedPoints; state.acceptedPoints = acceptedPoints;
state.totalMileageSamples = totalMileageSamples; state.totalMileageSamples = totalMileageSamples;
state.outOfOrderPoints = outOfOrderPoints; state.outOfOrderPoints = outOfOrderPoints;
@@ -112,11 +109,9 @@ public final class Jt808DailyMileageState {
if (current < lastTotalMileageKm) { if (current < lastTotalMileageKm) {
odometerAnomalies++; odometerAnomalies++;
lastTotalMileageKm = current; lastTotalMileageKm = current;
odometerMileageKm = 0.0;
return; return;
} }
lastTotalMileageKm = current; lastTotalMileageKm = current;
odometerMileageKm = current - firstTotalMileageKm;
} }
private OptionalDouble totalMileageDifference() { private OptionalDouble totalMileageDifference() {
@@ -160,10 +155,6 @@ public final class Jt808DailyMileageState {
return lastEventTime; return lastEventTime;
} }
public double odometerMileageKm() {
return odometerMileageKm;
}
public double lastTotalMileageKm() { public double lastTotalMileageKm() {
return lastTotalMileageKm; return lastTotalMileageKm;
} }

View File

@@ -66,7 +66,6 @@ public final class RedisJt808MileageStateStore implements Jt808MileageStateStore
PointSnapshot lastPoint, PointSnapshot lastPoint,
Double firstTotalMileageKm, Double firstTotalMileageKm,
Double lastTotalMileageKm, Double lastTotalMileageKm,
double odometerMileageKm,
int acceptedPoints, int acceptedPoints,
Integer totalMileageSamples, Integer totalMileageSamples,
int outOfOrderPoints, int outOfOrderPoints,
@@ -83,7 +82,6 @@ public final class RedisJt808MileageStateStore implements Jt808MileageStateStore
null, null,
finiteOrNull(state.firstTotalMileageKm()), finiteOrNull(state.firstTotalMileageKm()),
finiteOrNull(state.lastTotalMileageKm()), finiteOrNull(state.lastTotalMileageKm()),
state.odometerMileageKm(),
state.acceptedPoints(), state.acceptedPoints(),
state.totalMileageSamples(), state.totalMileageSamples(),
state.outOfOrderPoints(), state.outOfOrderPoints(),
@@ -100,7 +98,6 @@ public final class RedisJt808MileageStateStore implements Jt808MileageStateStore
restoredLastEventTime(), restoredLastEventTime(),
nanIfNull(firstTotalMileageKm), nanIfNull(firstTotalMileageKm),
nanIfNull(lastTotalMileageKm), nanIfNull(lastTotalMileageKm),
odometerMileageKm,
acceptedPoints, acceptedPoints,
restoredTotalMileageSamples(), restoredTotalMileageSamples(),
outOfOrderPoints, outOfOrderPoints,

View File

@@ -19,7 +19,6 @@ class Jt808DailyMileageStateTest {
assertThat(state.acceptedPoints()).isEqualTo(1); assertThat(state.acceptedPoints()).isEqualTo(1);
assertThat(state.totalMileageSamples()).isEqualTo(1); assertThat(state.totalMileageSamples()).isEqualTo(1);
assertThat(state.odometerMileageKm()).isZero();
assertThat(state.firstTotalMileageKm()).isEqualTo(100.0); assertThat(state.firstTotalMileageKm()).isEqualTo(100.0);
assertThat(state.lastTotalMileageKm()).isEqualTo(100.0); assertThat(state.lastTotalMileageKm()).isEqualTo(100.0);
assertThat(state.toVehicleDailyStatResult()).isEmpty(); assertThat(state.toVehicleDailyStatResult()).isEmpty();
@@ -28,7 +27,7 @@ class Jt808DailyMileageStateTest {
} }
@Test @Test
void orderedPointUpdatesGpsSpeedAndOdometerMileage() { void orderedPointsCalculateDailyMileageFromTotalMileageDifference() {
Jt808DailyMileageState state = Jt808DailyMileageState.empty("VIN001", "VIN001", "13900000001", Jt808DailyMileageState state = Jt808DailyMileageState.empty("VIN001", "VIN001", "13900000001",
LocalDate.of(2026, 6, 30)); LocalDate.of(2026, 6, 30));
state.apply(point("2026-06-30T00:00:00Z", 120.000000, 30.000000, 36.0, 100.0)); state.apply(point("2026-06-30T00:00:00Z", 120.000000, 30.000000, 36.0, 100.0));
@@ -37,7 +36,6 @@ class Jt808DailyMileageStateTest {
assertThat(state.acceptedPoints()).isEqualTo(2); assertThat(state.acceptedPoints()).isEqualTo(2);
assertThat(state.totalMileageSamples()).isEqualTo(2); assertThat(state.totalMileageSamples()).isEqualTo(2);
assertThat(state.odometerMileageKm()).isCloseTo(1.2, offset(0.000001));
assertThat(state.firstTotalMileageKm()).isEqualTo(100.0); assertThat(state.firstTotalMileageKm()).isEqualTo(100.0);
assertThat(state.lastTotalMileageKm()).isEqualTo(101.2); assertThat(state.lastTotalMileageKm()).isEqualTo(101.2);
assertThat(state.toVehicleDailyStatResult()).isPresent(); assertThat(state.toVehicleDailyStatResult()).isPresent();
@@ -66,7 +64,6 @@ class Jt808DailyMileageStateTest {
state.apply(point("2026-06-30T00:01:40Z", 120.010370, 30.000000, 36.0, 99.5)); state.apply(point("2026-06-30T00:01:40Z", 120.010370, 30.000000, 36.0, 99.5));
assertThat(state.odometerMileageKm()).isZero();
assertThat(state.odometerAnomalies()).isEqualTo(1); assertThat(state.odometerAnomalies()).isEqualTo(1);
assertThat(state.toVehicleDailyStatResult()).isEmpty(); assertThat(state.toVehicleDailyStatResult()).isEmpty();
} }
@@ -79,13 +76,12 @@ class Jt808DailyMileageStateTest {
state.apply(point("2026-06-30T00:01:00Z", 120.000100, 30.000000, 36.0, 200.0)); state.apply(point("2026-06-30T00:01:00Z", 120.000100, 30.000000, 36.0, 200.0));
assertThat(state.odometerMileageKm()).isEqualTo(100.0);
assertThat(state.odometerAnomalies()).isZero(); assertThat(state.odometerAnomalies()).isZero();
assertThat(state.toVehicleDailyStatResult().orElseThrow().dailyMileageKm()).hasValue(100.0); assertThat(state.toVehicleDailyStatResult().orElseThrow().dailyMileageKm()).hasValue(100.0);
} }
@Test @Test
void gpsDistanceIsFallbackWhenTotalMileageIsMissing() { void totalMileageIsRequiredForDailyMileageMetric() {
Jt808DailyMileageState state = Jt808DailyMileageState.empty("VIN001", "VIN001", "13900000001", Jt808DailyMileageState state = Jt808DailyMileageState.empty("VIN001", "VIN001", "13900000001",
LocalDate.of(2026, 6, 30)); LocalDate.of(2026, 6, 30));
state.apply(point("2026-06-30T00:00:00Z", 120.000000, 30.000000, 36.0, null)); state.apply(point("2026-06-30T00:00:00Z", 120.000000, 30.000000, 36.0, null));

View File

@@ -2,6 +2,7 @@ package com.lingniu.ingest.vehiclestat.jt808;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ValueOperations;
@@ -31,14 +32,17 @@ class RedisJt808MileageStateStoreTest {
store.save(state); store.save(state);
ArgumentCaptor<String> json = ArgumentCaptor.forClass(String.class);
verify(values).set( verify(values).set(
org.mockito.ArgumentMatchers.eq("vehicle:mileage:jt808:daily:2026-06-30:VIN001"), org.mockito.ArgumentMatchers.eq("vehicle:mileage:jt808:daily:2026-06-30:VIN001"),
org.mockito.ArgumentMatchers.contains("\"vehicleKey\":\"VIN001\""), json.capture(),
org.mockito.ArgumentMatchers.eq(Duration.ofDays(3))); org.mockito.ArgumentMatchers.eq(Duration.ofDays(3)));
assertThat(json.getValue()).contains("\"vehicleKey\":\"VIN001\"");
assertThat(json.getValue()).doesNotContain("odometerMileageKm");
} }
@Test @Test
void loadsStateFromJson() { void loadsStateFromLegacyJson() {
StringRedisTemplate redis = mock(StringRedisTemplate.class); StringRedisTemplate redis = mock(StringRedisTemplate.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ValueOperations<String, String> values = mock(ValueOperations.class); ValueOperations<String, String> values = mock(ValueOperations.class);