diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java index c3960161e..27466970d 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java @@ -24,7 +24,7 @@ public class AggregatorBarometerTest { addSensorValue(subject, new float[]{1015f, 1015.01f, 1015.02f, 1015.03f, 1015.04f, 1015.05f, 1015.06f, 1015.07f, 1015.08f, 1015.09f, 1015.10f, 1015.11f, 1015.12f, 1015.13f, 1018f, 1018.1f, 1018.1f, 1018.1f, 1018.1f}); // then - Assert.assertEquals(0f, subject.aggregatedValue.gain_m(), 0.01); - Assert.assertEquals(15f, subject.aggregatedValue.loss_m(), 0.01); + Assert.assertEquals(0f, subject.output.gain_m(), 0.01); + Assert.assertEquals(15f, subject.output.loss_m(), 0.01); } } \ No newline at end of file diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java index 51b41cd15..f7f06e13e 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java @@ -2,6 +2,7 @@ package de.dennisguse.opentracks.sensors.sensorData; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -12,7 +13,6 @@ import java.time.Instant; import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; -import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.sensors.UintUtils; import de.dennisguse.opentracks.sensors.driver.CyclingCadenceBluetooth; import de.dennisguse.opentracks.sensors.driver.CyclingDistanceSpeedBluetooth; @@ -93,7 +93,7 @@ public class SensorDataCyclingTest { // then // TODO See #953 // assertEquals(60, current.getValue().getRPM(), 0.01); - assertEquals(Cadence.of(0), current.getAggregatedValue(Instant.MIN)); + assertNull(current.getAggregatedValue(Instant.MIN)); } @Test @@ -120,11 +120,10 @@ public class SensorDataCyclingTest { current.add(Instant.MIN, new CyclingDistanceSpeedBluetooth.WheelData(UintUtils.UINT32_MAX - 1, 1024)); current.add(Instant.MIN, new CyclingDistanceSpeedBluetooth.WheelData(0, 2048)); - // then // TODO See #953 // assertEquals(2, current.getValue().getDistance().toM(), 0.01); // assertEquals(2, current.getValue().getSpeed().toMPS(), 0.01); - assertEquals(new AggregatorCyclingDistanceSpeed.Data(Distance.ZERO, Distance.ZERO, Speed.ZERO), current.getAggregatedValue(Instant.MIN)); + assertNull(current.getAggregatedValue(Instant.MIN)); } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java index d61cd8a5a..0cec85cc3 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java @@ -1,17 +1,20 @@ package de.dennisguse.opentracks.sensors.sensorData; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.time.Duration; import java.time.Instant; -public abstract class Aggregator { +public abstract class Aggregator { private static final Duration MAX_SENSOR_DATE_SET_AGE = Duration.ofSeconds(5); - protected Raw previous; + @Nullable + protected Raw previous; - protected Output aggregatedValue; + //TODO Make private + protected OutputType output; private final String sensorAddress; private final String sensorName; @@ -25,57 +28,47 @@ public abstract class Aggregator { return sensorName != null ? sensorName : sensorAddress; } - public final void add(Instant now, Input current) { - Raw next = new Raw<>(now, current); + public final void add(Instant now, InputType current) { + Raw next = new Raw<>(now, current); computeValue(next); previous = next; } - protected abstract void computeValue(Raw current); + protected abstract void computeValue(Raw current); /** * @return did we process data from a sensor. * NOTE: for some sensors this may require more than one measurement. */ public boolean hasReceivedData() { - return aggregatedValue != null; + return output != null; } - @Deprecated //TODO Remove: for sensor there is no default value. Make getAggregatedValue() @Nullable - @NonNull - protected abstract Output getNoneValue(); - - @Deprecated //TODO Removed; just implemented for refactoring. This code is bypassing core functionality of this class. - public Output getAggregatedValue() { - return aggregatedValue; - } - - @NonNull - public Output getAggregatedValue(Instant now) { - if (!hasReceivedData()) { - return getNoneValue(); - } + @Nullable + protected OutputType getAggregatedValue(Instant now) { if (isOutdated(now)) { - resetImmediate(); + resetOutdated(); } - return aggregatedValue; + return output; } @NonNull - public SensorData getAggregatedValueWithSensorName(Instant now) { + public SensorData getAggregatedValueWithSensorName(Instant now) { return new SensorData<>(getAggregatedValue(now), getSensorNameOrAddress()); } /** * Reset short-term (i.e., non-aggregated) values that were directly derived from sensor data. */ - protected abstract void resetImmediate(); + protected void resetOutdated() { + output = null; + }; /** * Reset long-term (i.e., aggregated) values (more than derived from previous SensorData) like overall distance. */ - public abstract void resetAggregated(); + public void resetAggregated() {}; /** * Is the data recent considering the current time. @@ -99,7 +92,7 @@ public abstract class Aggregator { @NonNull @Override public String toString() { - return "sensorAddress=" + sensorAddress + " data=" + aggregatedValue; + return "sensorAddress=" + sensorAddress + " data=" + output; } protected record Raw( diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometer.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometer.java index bd6b1b017..c5b9be679 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometer.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometer.java @@ -1,7 +1,5 @@ package de.dennisguse.opentracks.sensors.sensorData; -import androidx.annotation.NonNull; - import de.dennisguse.opentracks.data.models.Altitude; import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.AtmosphericPressure; @@ -19,31 +17,28 @@ public class AggregatorBarometer extends Aggregator current) { if (previous == null) { lastAcceptedSensorValue = current.value(); - aggregatedValue = getNoneValue(); + output = new AltitudeGainLoss(0f, 0f); return; } PressureSensorUtils.AltitudeChange altitudeChange = PressureSensorUtils.computeChangesWithSmoothing_m(lastAcceptedSensorValue, previous.value(), current.value()); if (altitudeChange != null) { - aggregatedValue = new AltitudeGainLoss(aggregatedValue.gain_m() + altitudeChange.getAltitudeGain_m(), aggregatedValue.loss_m() + altitudeChange.getAltitudeLoss_m()); + if (output == null) { + output = new AltitudeGainLoss(0f, 0f); + } + output = new AltitudeGainLoss(output.gain_m() + altitudeChange.getAltitudeGain_m(), output.loss_m() + altitudeChange.getAltitudeLoss_m()); lastAcceptedSensorValue = altitudeChange.currentSensorValue(); } } @Override - protected void resetImmediate() { + protected void resetOutdated() { } @Override public void resetAggregated() { - aggregatedValue = getNoneValue(); - } - - @NonNull - @Override - protected AltitudeGainLoss getNoneValue() { - return new AltitudeGainLoss(0f, 0f); + output = null; } public record Data(Altitude gain, Altitude loss) {} diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorCyclingCadence.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorCyclingCadence.java index 6f109d8e9..7cb7c21fa 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorCyclingCadence.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorCyclingCadence.java @@ -2,8 +2,6 @@ package de.dennisguse.opentracks.sensors.sensorData; import android.util.Log; -import androidx.annotation.NonNull; - import java.time.Duration; import de.dennisguse.opentracks.data.models.Cadence; @@ -32,32 +30,18 @@ public class AggregatorCyclingCadence extends Aggregator current) { - this.aggregatedValue = current.value().power(); - } - - @Override - protected void resetImmediate() { - aggregatedValue = getNoneValue(); - } - - @Override - public void resetAggregated() { - } - - @NonNull - @Override - protected Power getNoneValue() { - return Power.of(0f); + this.output = current.value().power(); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorGPS.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorGPS.java index af6731b86..f57f3bbfb 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorGPS.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorGPS.java @@ -10,19 +10,13 @@ import de.dennisguse.opentracks.data.models.Position; public class AggregatorGPS extends Aggregator { - public AggregatorGPS(String sensorAddress, String sensorName) { super(sensorAddress, sensorName); } @Override protected void computeValue(Raw current) { - aggregatedValue = Position.of(current.value(), current.time()); - } - - @Override - protected void resetImmediate() { - aggregatedValue = Position.empty(); + output = Position.of(current.value(), current.time()); } @Override @@ -32,19 +26,15 @@ public class AggregatorGPS extends Aggregator { * The data is too large to save it more often than needed (i.e., duplicated values). * TODO: this behavior can be changed if TrackRecordingManager.insertTrackPoint() would strip GPS data if it was already saved. This would simplify TrackPointCreator.createCurrentTrackPoint() */ - aggregatedValue = Position.empty(); - } - - @NonNull - @Override - protected Position getNoneValue() { - return Position.empty(); + output = null; } @NonNull @Override public Position getAggregatedValue(Instant now) { - return super.getAggregatedValue(now) - .with(now); + Position value = super.getAggregatedValue(now); + if (value == null) value = Position.empty(); + + return value.with(now); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorHeartRate.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorHeartRate.java index 22c7bea24..b7bc6ad9d 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorHeartRate.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorHeartRate.java @@ -1,7 +1,5 @@ package de.dennisguse.opentracks.sensors.sensorData; -import androidx.annotation.NonNull; - import de.dennisguse.opentracks.data.models.HeartRate; public class AggregatorHeartRate extends Aggregator { @@ -13,22 +11,7 @@ public class AggregatorHeartRate extends Aggregator { @Override protected void computeValue(Raw current) { if (current.value().isValid()) { - this.aggregatedValue = current.value(); + this.output = current.value(); } } - - @Override - protected void resetImmediate() { - aggregatedValue = getNoneValue(); - } - - @Override - public void resetAggregated() { - } - - @NonNull - @Override - protected HeartRate getNoneValue() { - return HeartRate.of(0); - } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorRunning.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorRunning.java index 8cdf81b93..a5c7bc34e 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorRunning.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorRunning.java @@ -27,33 +27,31 @@ public final class AggregatorRunning extends Aggregator } protected void computeValue(Raw current) { - this.aggregatedValue = current.value(); + this.output = current.value(); } - @NonNull - protected Temperature getNoneValue() { - return Temperature.ofCentiCelsius(0); - } - - protected void resetImmediate() { - aggregatedValue = getNoneValue(); - } - - public void resetAggregated() {}; - @Override protected Duration getMaxSensorAge() { return Duration.ofMinutes(1); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorData.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorData.java index 104bf718a..7758b02f1 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorData.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorData.java @@ -1,7 +1,11 @@ package de.dennisguse.opentracks.sensors.sensorData; +import androidx.annotation.Nullable; + public record SensorData( + + @Nullable T data, String sensorNameOrAddress