From a1a363698f22a308129ba56ce6585d41042f907f Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sat, 31 Jan 2026 19:45:32 +0100 Subject: [PATCH] SensorHandler now interacts with Aggregator. --- .../sensors/AltitudeChangeHandler.java | 6 +- .../sensors/CyclingCadenceHandler.java | 6 +- .../sensors/CyclingDistanceSpeedHandler.java | 2 +- .../sensors/CyclingPowerHandler.java | 3 +- .../opentracks/sensors/HeartRateHandler.java | 5 +- .../RunningSpeedCadenceDistanceHandler.java | 2 +- .../opentracks/sensors/SensorHandler.java | 31 ++++++--- .../opentracks/sensors/SensorManager.java | 66 +++++++++++-------- .../sensors/TemperatureHandler.java | 5 +- .../sensors/sensorData/Aggregator.java | 4 +- 10 files changed, 75 insertions(+), 55 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/sensors/AltitudeChangeHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/AltitudeChangeHandler.java index f909fc077..c79550143 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/AltitudeChangeHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/AltitudeChangeHandler.java @@ -3,19 +3,19 @@ package de.dennisguse.opentracks.sensors; import androidx.annotation.NonNull; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.AtmosphericPressure; import de.dennisguse.opentracks.sensors.driver.BarometerBluetooth; import de.dennisguse.opentracks.sensors.driver.BarometerInternal; import de.dennisguse.opentracks.sensors.driver.BluetoothDriver; import de.dennisguse.opentracks.sensors.driver.Driver; -import de.dennisguse.opentracks.sensors.sensorData.Aggregator; import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer; /** * Estimates the altitude gain and altitude loss using the device's pressure sensor (i.e., barometer). */ //TODO Rename class -public class AltitudeChangeHandler extends SensorHandler { +public class AltitudeChangeHandler extends SensorHandler { public AltitudeChangeHandler(SensorManager sensorManager) { super(sensorManager); @@ -44,7 +44,7 @@ public class AltitudeChangeHandler extends SensorHandler { @NonNull @Override - public Aggregator createAggregator() { + public AggregatorBarometer createAggregator() { return new AggregatorBarometer("", null); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/CyclingCadenceHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/CyclingCadenceHandler.java index 4fde2f997..64de38dad 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/CyclingCadenceHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/CyclingCadenceHandler.java @@ -3,13 +3,13 @@ package de.dennisguse.opentracks.sensors; import androidx.annotation.NonNull; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.sensors.driver.BluetoothDriver; import de.dennisguse.opentracks.sensors.driver.CyclingCadenceBluetooth; import de.dennisguse.opentracks.sensors.driver.Driver; -import de.dennisguse.opentracks.sensors.sensorData.Aggregator; import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence; -public class CyclingCadenceHandler extends SensorHandler { +public class CyclingCadenceHandler extends SensorHandler { protected CyclingCadenceHandler(SensorManager sensorManager) { super(sensorManager); @@ -27,7 +27,7 @@ public class CyclingCadenceHandler extends SensorHandler createAggregator() { + protected AggregatorCyclingCadence createAggregator() { return new AggregatorCyclingCadence("", null); } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/CyclingDistanceSpeedHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/CyclingDistanceSpeedHandler.java index 54d07c3b4..76ba0c82d 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/CyclingDistanceSpeedHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/CyclingDistanceSpeedHandler.java @@ -8,7 +8,7 @@ import de.dennisguse.opentracks.sensors.driver.CyclingDistanceSpeedBluetooth; import de.dennisguse.opentracks.sensors.driver.Driver; import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingDistanceSpeed; -public class CyclingDistanceSpeedHandler extends SensorHandler { +public class CyclingDistanceSpeedHandler extends SensorHandler { protected CyclingDistanceSpeedHandler(SensorManager sensorManager) { super(sensorManager); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/CyclingPowerHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/CyclingPowerHandler.java index 65f43d2e4..1d5065c79 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/CyclingPowerHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/CyclingPowerHandler.java @@ -3,12 +3,13 @@ package de.dennisguse.opentracks.sensors; import androidx.annotation.NonNull; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.sensors.driver.BluetoothDriver; import de.dennisguse.opentracks.sensors.driver.CyclingPowerBluetooth; import de.dennisguse.opentracks.sensors.driver.Driver; import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingPower; -public class CyclingPowerHandler extends SensorHandler { +public class CyclingPowerHandler extends SensorHandler { protected CyclingPowerHandler(SensorManager sensorManager) { super(sensorManager); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/HeartRateHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/HeartRateHandler.java index b4e911f24..5f61fccd6 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/HeartRateHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/HeartRateHandler.java @@ -7,10 +7,9 @@ import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.sensors.driver.BluetoothDriver; import de.dennisguse.opentracks.sensors.driver.Driver; import de.dennisguse.opentracks.sensors.driver.HeartRateBluetooth; -import de.dennisguse.opentracks.sensors.sensorData.Aggregator; import de.dennisguse.opentracks.sensors.sensorData.AggregatorHeartRate; -public class HeartRateHandler extends SensorHandler { +public class HeartRateHandler extends SensorHandler { protected HeartRateHandler(SensorManager sensorManager) { super(sensorManager); @@ -28,7 +27,7 @@ public class HeartRateHandler extends SensorHandler { @NonNull @Override - protected Aggregator createAggregator() { + protected AggregatorHeartRate createAggregator() { return new AggregatorHeartRate("", null); } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/RunningSpeedCadenceDistanceHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/RunningSpeedCadenceDistanceHandler.java index e2b2d6333..c39c246cd 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/RunningSpeedCadenceDistanceHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/RunningSpeedCadenceDistanceHandler.java @@ -8,7 +8,7 @@ import de.dennisguse.opentracks.sensors.driver.Driver; import de.dennisguse.opentracks.sensors.driver.RunningSpeedAndCadenceBluetooth; import de.dennisguse.opentracks.sensors.sensorData.AggregatorRunning; -public class RunningSpeedCadenceDistanceHandler extends SensorHandler { +public class RunningSpeedCadenceDistanceHandler extends SensorHandler { protected RunningSpeedCadenceDistanceHandler(SensorManager sensorManager) { super(sensorManager); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/SensorHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/SensorHandler.java index fdb684227..6cbe671d7 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/SensorHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/SensorHandler.java @@ -3,23 +3,27 @@ package de.dennisguse.opentracks.sensors; import android.content.Context; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import java.time.Instant; + import de.dennisguse.opentracks.sensors.driver.Driver; import de.dennisguse.opentracks.sensors.driver.DriverObserver; import de.dennisguse.opentracks.sensors.sensorData.Aggregator; +import de.dennisguse.opentracks.sensors.sensorData.SensorData; import de.dennisguse.opentracks.settings.PreferencesUtils; -public abstract class SensorHandler { +public abstract class SensorHandler { private final SensorManager sensorManager; private Driver driver; - private Aggregator aggregator; + private Aggregator aggregator; - protected final DriverObserver driverObserver = new DriverObserver<>() { + protected final DriverObserver driverObserver = new DriverObserver<>() { @Override public void onConnect() { SensorHandler.this.aggregator = createAggregator(); @@ -31,7 +35,7 @@ public abstract class SensorHandler { } @Override - public void onData(T value) { + public void onData(AggregatorInput value) { SensorHandler.this.aggregator.add(sensorManager.getNow(), value); sensorManager.onChange(); } @@ -85,7 +89,7 @@ public abstract class SensorHandler { } @NonNull - protected abstract Aggregator createAggregator(); + protected abstract Aggregator createAggregator(); protected abstract int getSensorPreferenceKey(); @@ -93,14 +97,23 @@ public abstract class SensorHandler { return sensorManager.getContext(); } - //TODO Try to keep aggregator private. - Aggregator getAggregator() { - return aggregator; + void resetAggregated() { + if (aggregator != null) { + aggregator.resetAggregated(); + } + } + + @Nullable + SensorData getSensorData(Instant now) { + if (aggregator == null) return null; + if (!aggregator.hasReceivedData()) return null; + + return aggregator.getAggregatedValueWithSensorName(now); } //TODO REMOVE @VisibleForTesting - public void setAggregator(Aggregator aggregator) { + public void setAggregator(Aggregator aggregator) { this.aggregator = aggregator; } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java index 8c65baec5..5589e1ff2 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java @@ -18,7 +18,6 @@ import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.sensors.sensorData.Aggregator; -import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer; import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence; import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingDistanceSpeed; import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingPower; @@ -121,13 +120,13 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange Log.i(TAG, "Resetting data"); - if (heartRateHandler.getAggregator() != null) heartRateHandler.getAggregator().resetAggregated(); - if (temperatureHandler.getAggregator() != null) temperatureHandler.getAggregator().resetAggregated(); - if (cyclingCadenceHandler.getAggregator() != null) cyclingCadenceHandler.getAggregator().resetAggregated(); - if (cyclingDistanceSpeedHandler.getAggregator() != null) cyclingDistanceSpeedHandler.getAggregator().resetAggregated(); - if (cyclingPowerHandler.getAggregator() != null) cyclingPowerHandler.getAggregator().resetAggregated(); - if (runningSpeedCadenceDistanceHandler.getAggregator() != null) runningSpeedCadenceDistanceHandler.getAggregator().resetAggregated(); - if (altitudeChangeHandler.getAggregator() != null) altitudeChangeHandler.getAggregator().resetAggregated(); + heartRateHandler.resetAggregated(); + temperatureHandler.resetAggregated(); + cyclingCadenceHandler.resetAggregated(); + cyclingDistanceSpeedHandler.resetAggregated(); + cyclingPowerHandler.resetAggregated(); + runningSpeedCadenceDistanceHandler.resetAggregated(); + altitudeChangeHandler.resetAggregated(); if (gpsManager.getAggregatorGPS() != null) gpsManager.getAggregatorGPS().resetAggregated(); } @@ -189,8 +188,9 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange } private SensorData getHeartRate(Instant now) { - if (heartRateHandler.getAggregator() != null) { - SensorData value = ((AggregatorHeartRate) heartRateHandler.getAggregator()).getAggregatedValueWithSensorName(now); + SensorData value = heartRateHandler.getSensorData(now); + if (value != null) { + //TODO Move this check into HeartRateHandler if (value.data().isValid()) return value; } @@ -199,25 +199,32 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange } private SensorData getCadence(Instant now) { - if (cyclingCadenceHandler.getAggregator() != null) { - return ((AggregatorCyclingCadence) cyclingCadenceHandler.getAggregator()).getAggregatedValueWithSensorName(now); + { + SensorData value = cyclingCadenceHandler.getSensorData(now); + if (value != null) { + return cyclingCadenceHandler.getSensorData(now); + } } - if (runningSpeedCadenceDistanceHandler.getAggregator() != null && runningSpeedCadenceDistanceHandler.getAggregator().hasReceivedData() && ((AggregatorRunning) runningSpeedCadenceDistanceHandler.getAggregator()).getAggregatedValue(now).cadence() != null) { - return new SensorData<>(((AggregatorRunning) runningSpeedCadenceDistanceHandler.getAggregator()).getAggregatedValue().cadence(), runningSpeedCadenceDistanceHandler.getAggregator().getSensorNameOrAddress()); + SensorData value = runningSpeedCadenceDistanceHandler.getSensorData(now); + if (value != null && value.data().cadence() != null) { + return new SensorData<>(value.data().cadence(), value.sensorNameOrAddress()); } return null; } private SensorData getDistance(Instant now) { - if (cyclingDistanceSpeedHandler.getAggregator() != null && cyclingDistanceSpeedHandler.getAggregator().hasReceivedData()) { - return new SensorData<>(((AggregatorCyclingDistanceSpeed) cyclingDistanceSpeedHandler.getAggregator()).getAggregatedValue(now).distanceOverall(), cyclingDistanceSpeedHandler.getAggregator().getSensorNameOrAddress()); + { + SensorData value = cyclingDistanceSpeedHandler.getSensorData(now); + if (value != null) { + return new SensorData<>(value.data().distanceOverall(), value.sensorNameOrAddress()); + } } - if (runningSpeedCadenceDistanceHandler.getAggregator() != null && runningSpeedCadenceDistanceHandler.getAggregator().hasReceivedData()) { - return new SensorData<>(((AggregatorRunning) runningSpeedCadenceDistanceHandler.getAggregator()).getAggregatedValue(now).distance(), runningSpeedCadenceDistanceHandler.getAggregator().getSensorNameOrAddress()); - + SensorData value = runningSpeedCadenceDistanceHandler.getSensorData(now); + if (value != null) { + return new SensorData<>(value.data().distance(), value.sensorNameOrAddress()); } return null; @@ -225,13 +232,16 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange //TOOD simplify? private SensorData getSpeed(Instant now) { - - if (cyclingDistanceSpeedHandler.getAggregator() != null && cyclingDistanceSpeedHandler.getAggregator().hasReceivedData() && ((AggregatorCyclingDistanceSpeed) cyclingDistanceSpeedHandler.getAggregator()).getAggregatedValue(now).speed() != null) { - return new SensorData<>(((AggregatorCyclingDistanceSpeed) cyclingDistanceSpeedHandler.getAggregator()).getAggregatedValue(now).speed(), cyclingDistanceSpeedHandler.getAggregator().getSensorNameOrAddress()); + { + SensorData value = cyclingDistanceSpeedHandler.getSensorData(now); + if (value != null && value.data() != null && value.data().speed() != null) { + return new SensorData<>(value.data().speed(), value.sensorNameOrAddress()); + } } - if (runningSpeedCadenceDistanceHandler.getAggregator() != null && runningSpeedCadenceDistanceHandler.getAggregator().hasReceivedData() && ((AggregatorRunning) runningSpeedCadenceDistanceHandler.getAggregator()).getAggregatedValue(now).speed() != null) { - return new SensorData<>(((AggregatorRunning) runningSpeedCadenceDistanceHandler.getAggregator()).getAggregatedValue().speed(), runningSpeedCadenceDistanceHandler.getAggregator().getSensorNameOrAddress()); + SensorData value = runningSpeedCadenceDistanceHandler.getSensorData(now); + if (value != null && value.data() != null && value.data().speed() != null) { + return new SensorData<>(value.data().speed(), value.sensorNameOrAddress()); } return null; @@ -273,7 +283,6 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange observer.onChange(); } - // TODO inline with stop()? @VisibleForTesting public void clear() { Log.i(TAG, "Removing all aggregators"); @@ -307,17 +316,16 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange public SensorDataSet getSensorDataSet(Instant now) { AggregatorGPS gps = gpsManager.getAggregatorGPS(); - AggregatorBarometer barometer = (AggregatorBarometer) altitudeChangeHandler.getAggregator(); return new SensorDataSet( gps != null && gps.hasReceivedData() ? gps.getAggregatedValueWithSensorName(now) : new SensorData<>(Position.of(now), ""), getSpeed(now), getDistance(now), getHeartRate(now), - temperatureHandler.getAggregator() != null && temperatureHandler.getAggregator().hasReceivedData() ? ((AggregatorTemperature) temperatureHandler.getAggregator()).getAggregatedValueWithSensorName(now) : null, + temperatureHandler.getSensorData(now), getCadence(now), - cyclingPowerHandler.getAggregator() != null && cyclingPowerHandler.getAggregator().hasReceivedData() ? ((AggregatorCyclingPower) cyclingPowerHandler.getAggregator()).getAggregatedValueWithSensorName(now) : null, - barometer != null && barometer.hasReceivedData() ? barometer.getAggregatedValueWithSensorName(now) : null + cyclingPowerHandler.getSensorData(now), + altitudeChangeHandler.getSensorData(now) ); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/TemperatureHandler.java b/src/main/java/de/dennisguse/opentracks/sensors/TemperatureHandler.java index 5b990d72b..823732b20 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/TemperatureHandler.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/TemperatureHandler.java @@ -7,10 +7,9 @@ import de.dennisguse.opentracks.data.models.Temperature; import de.dennisguse.opentracks.sensors.driver.BluetoothDriver; import de.dennisguse.opentracks.sensors.driver.Driver; import de.dennisguse.opentracks.sensors.driver.TemperatureBluetooth; -import de.dennisguse.opentracks.sensors.sensorData.Aggregator; import de.dennisguse.opentracks.sensors.sensorData.AggregatorTemperature; -public class TemperatureHandler extends SensorHandler { +public class TemperatureHandler extends SensorHandler { protected TemperatureHandler(SensorManager sensorManager) { super(sensorManager); @@ -28,7 +27,7 @@ public class TemperatureHandler extends SensorHandler { @NonNull @Override - protected Aggregator createAggregator() { + protected AggregatorTemperature createAggregator() { return new AggregatorTemperature("", null); } 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 d039c74e2..4b5be814c 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java @@ -25,12 +25,12 @@ public abstract class Aggregator { this.sensorName = sensorName; } - public String getSensorNameOrAddress() { + private String getSensorNameOrAddress() { return sensorName != null ? sensorName : sensorAddress; } public final void add(Instant now, Input current) { - Raw next = new Raw<>(now, current); + Raw next = new Raw<>(now, current); computeValue(next); previous = next; }