From 0eda1eed1dd4516caf724a701f6941bcac4e3c90 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sun, 16 Jan 2022 15:11:35 +0100 Subject: [PATCH] Introduced value objects for heartrate, cadence, and power. Fixes #896. --- .../opentracks/chart/ChartPointTest.java | 4 +- .../opentracks/content/data/TestDataUtil.java | 4 +- .../content/data/TestSensorDataUtil.java | 12 ++- .../data/CustomContentProviderUtilsTest.java | 78 ++++++++++--------- .../io/file/importer/ExportImportTest.java | 21 ++--- .../io/file/importer/TrackPointAssert.java | 6 +- .../sensors/BluetoothUtilsTest.java | 3 +- .../sensorData/SensorDataCyclingTest.java | 43 +++++----- .../viewmodels/StatisticDataBuilderTest.java | 23 +++--- .../opentracks/chart/ChartPoint.java | 6 +- .../opentracks/data/ContentProviderUtils.java | 28 ++++--- .../opentracks/data/models/Cadence.java | 43 ++++++++++ .../opentracks/data/models/HeartRate.java | 43 ++++++++++ .../opentracks/data/models/Power.java | 43 ++++++++++ .../opentracks/data/models/TrackPoint.java | 46 +++++++---- .../io/file/exporter/GPXTrackExporter.java | 6 +- .../io/file/exporter/KMLTrackExporter.java | 6 +- .../io/file/importer/GpxTrackImporter.java | 4 +- .../io/file/importer/KmlTrackImporter.java | 10 +-- .../sensors/BluetoothConnectionManager.java | 21 ++--- .../sensors/BluetoothRemoteSensorManager.java | 8 +- .../opentracks/sensors/BluetoothUtils.java | 9 ++- .../sensors/sensorData/SensorDataCycling.java | 29 +++---- .../sensorData/SensorDataCyclingPower.java | 12 +-- .../sensorData/SensorDataHeartRate.java | 12 +-- .../sensors/sensorData/SensorDataRunning.java | 17 ++-- .../sensors/sensorData/SensorDataSet.java | 18 +++-- .../opentracks/stats/SensorStatistics.java | 28 ++++--- .../opentracks/util/StringUtils.java | 21 ++--- .../viewmodels/StatisticDataBuilder.java | 5 +- 30 files changed, 397 insertions(+), 212 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/data/models/Cadence.java create mode 100644 src/main/java/de/dennisguse/opentracks/data/models/HeartRate.java create mode 100644 src/main/java/de/dennisguse/opentracks/data/models/Power.java diff --git a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java index 5289251b3..0777e16bf 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java @@ -77,8 +77,8 @@ public class ChartPointTest { public void create_sensorAvailable() { // given TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint(); - trackPoint.setHeartRate_bpm(100f); - trackPoint.setCadence_rpm(101f); + trackPoint.setHeartRate(100f); + trackPoint.setCadence(101f); trackPoint.setPower(102f); TrackStatistics statistics = new TrackStatistics(); diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index 27df7b981..10b5dd6a0 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -124,8 +124,8 @@ public class TestDataUtil { trackPoint.setAltitude(i * ALTITUDE_INTERVAL); trackPoint.setSpeed(Speed.of(5f + (i / 10f))); - trackPoint.setHeartRate_bpm(100f + i); - trackPoint.setCadence_rpm(300f + i); + trackPoint.setHeartRate(100f + i); + trackPoint.setCadence(300f + i); trackPoint.setPower(400f + i); trackPoint.setAltitudeGain(ALTITUDE_GAIN); trackPoint.setAltitudeLoss(ALTITUDE_LOSS); diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java index 1b56ea7d6..fc7ca69d8 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java @@ -20,9 +20,15 @@ public class TestSensorDataUtil { int i = trackPointList.size() + 1; tp.setLatitude(TestDataUtil.INITIAL_LATITUDE + (double) i / 10000.0); tp.setLongitude(TestDataUtil.INITIAL_LONGITUDE - (double) i / 10000.0); - tp.setHeartRate_bpm(hr); - tp.setCadence_rpm(cadence); - tp.setPower(power); + if (hr != null) { + tp.setHeartRate(hr); + } + if (cadence != null) { + tp.setCadence(cadence); + } + if (power != null) { + tp.setPower(power); + } tp.setHorizontalAccuracy(Distance.of(1f)); tp.setAltitude(1f); tp.setSpeed(Speed.of(5f + (i / 10f))); diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java index c05bdf244..7d8f4181d 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java @@ -52,6 +52,7 @@ import java.util.stream.Collectors; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.TestSensorDataUtil; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; @@ -776,6 +777,7 @@ public class CustomContentProviderUtilsTest { when(cursorMock.getColumnIndexOrThrow(TrackPointsColumns.SENSOR_HEARTRATE)).thenReturn(6); when(cursorMock.isNull(6)).thenReturn(false); + when(cursorMock.getFloat(6)).thenReturn(75f); // when TrackPoint trackPoint = contentProviderUtils.createTrackPoint(cursorMock); @@ -785,7 +787,7 @@ public class CustomContentProviderUtilsTest { assertEquals(latitude, trackPoint.getLatitude(), 0.01); assertEquals(time, trackPoint.getTime().toEpochMilli()); assertEquals(speed, trackPoint.getSpeed().toMPS(), 0.01); - assertFalse(trackPoint.hasHeartRate()); + assertEquals(HeartRate.of(75f), trackPoint.getHeartRate()); } /** @@ -809,8 +811,8 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.createTrackAndInsert(contentProviderUtils, trackId, 10); TrackPoint trackPoint = TestDataUtil.createTrackPoint(5); - trackPoint.setHeartRate_bpm(1F); - trackPoint.setCadence_rpm(2F); + trackPoint.setHeartRate(1F); + trackPoint.setCadence(2F); trackPoint.setPower(3F); // when @@ -819,9 +821,9 @@ public class CustomContentProviderUtilsTest { // then List trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); assertTrue(trackPoints.get(10).hasHeartRate()); - assertEquals(trackPoint.getHeartRate_bpm(), trackPoints.get(10).getHeartRate_bpm(), 0.01); - assertEquals(trackPoint.getCadence_rpm(), trackPoints.get(10).getCadence_rpm(), 0.01); - assertEquals(trackPoint.getPower(), trackPoints.get(10).getPower(), 0.01); + assertEquals(trackPoint.getHeartRate(), trackPoints.get(10).getHeartRate()); + assertEquals(trackPoint.getCadence(), trackPoints.get(10).getCadence()); + assertEquals(trackPoint.getPower(), trackPoints.get(10).getPower()); } /** @@ -909,8 +911,8 @@ public class CustomContentProviderUtilsTest { TrackPoint trackPoint = TestDataUtil.createTrackPoint(1); trackPoint.setType(TrackPoint.Type.TRACKPOINT); trackPoint.setPower(null); - trackPoint.setCadence_rpm(null); - trackPoint.setHeartRate_bpm(null); + trackPoint.setCadence(null); + trackPoint.setHeartRate(null); trackPointList.add(trackPoint); Track.Id trackId = new Track.Id(System.currentTimeMillis()); Track track = TestDataUtil.createTrack(trackId); @@ -972,13 +974,13 @@ public class CustomContentProviderUtilsTest { // then assertTrue(sensorStatistics.hasHeartRate()); - assertEquals(sensorStatistics.getAvgHeartRate(), stats.avgHr, 0f); - assertEquals(sensorStatistics.getMaxHeartRate(), stats.maxHr, 0f); + assertEquals(sensorStatistics.getAvgHeartRate().getBPM(), stats.avgHr, 0f); + assertEquals(sensorStatistics.getMaxHeartRate().getBPM(), stats.maxHr, 0f); assertTrue(sensorStatistics.hasCadence()); - assertEquals(sensorStatistics.getAvgCadence(), stats.avgCadence, 0f); - assertEquals(sensorStatistics.getMaxCadence(), stats.maxCadence, 0f); + assertEquals(sensorStatistics.getAvgCadence().getRPM(), stats.avgCadence, 0f); + assertEquals(sensorStatistics.getMaxCadence().getRPM(), stats.maxCadence, 0f); assertTrue(sensorStatistics.hasPower()); - assertEquals(sensorStatistics.getAvgPower(), stats.avgPower, 0f); + assertEquals(sensorStatistics.getAvgPower().getW(), stats.avgPower, 0f); } @Test @@ -1004,8 +1006,8 @@ public class CustomContentProviderUtilsTest { // then assertTrue(sensorStatistics.hasHeartRate()); - assertEquals(sensorStatistics.getAvgHeartRate(), stats.avgHr, 0f); - assertEquals(sensorStatistics.getMaxHeartRate(), stats.maxHr, 0f); + assertEquals(sensorStatistics.getAvgHeartRate().getBPM(), stats.avgHr, 0f); + assertEquals(sensorStatistics.getMaxHeartRate().getBPM(), stats.maxHr, 0f); assertFalse(sensorStatistics.hasCadence()); assertFalse(sensorStatistics.hasPower()); } @@ -1034,8 +1036,8 @@ public class CustomContentProviderUtilsTest { // then assertFalse(sensorStatistics.hasHeartRate()); assertTrue(sensorStatistics.hasCadence()); - assertEquals(sensorStatistics.getAvgCadence(), stats.avgCadence, 0f); - assertEquals(sensorStatistics.getMaxCadence(), stats.maxCadence, 0f); + assertEquals(sensorStatistics.getAvgCadence().getRPM(), stats.avgCadence, 0f); + assertEquals(sensorStatistics.getMaxCadence().getRPM(), stats.maxCadence, 0f); assertFalse(sensorStatistics.hasPower()); } @@ -1064,7 +1066,7 @@ public class CustomContentProviderUtilsTest { assertFalse(sensorStatistics.hasHeartRate()); assertFalse(sensorStatistics.hasCadence()); assertTrue(sensorStatistics.hasPower()); - assertEquals(sensorStatistics.getAvgPower(), stats.avgPower, 0f); + assertEquals(sensorStatistics.getAvgPower().getW(), stats.avgPower, 0f); } @Test @@ -1097,11 +1099,11 @@ public class CustomContentProviderUtilsTest { TestSensorDataUtil.SensorDataStats stats = sensorDataUtil.computeStats(); // then - assertEquals(sensorStatistics.getAvgHeartRate(), stats.avgHr, 0f); - assertEquals(sensorStatistics.getMaxHeartRate(), stats.maxHr, 0f); - assertEquals(sensorStatistics.getAvgCadence(), stats.avgCadence, 0f); - assertEquals(sensorStatistics.getMaxCadence(), stats.maxCadence, 0f); - assertEquals(sensorStatistics.getAvgPower(), stats.avgPower, 0f); + assertEquals(sensorStatistics.getAvgHeartRate().getBPM(), stats.avgHr, 0f); + assertEquals(sensorStatistics.getMaxHeartRate().getBPM(), stats.maxHr, 0f); + assertEquals(sensorStatistics.getAvgCadence().getRPM(), stats.avgCadence, 0f); + assertEquals(sensorStatistics.getMaxCadence().getRPM(), stats.maxCadence, 0f); + assertEquals(sensorStatistics.getAvgPower().getW(), stats.avgPower, 0f); } @Test @@ -1142,11 +1144,11 @@ public class CustomContentProviderUtilsTest { TestSensorDataUtil.SensorDataStats stats = sensorDataUtil.computeStats(); // then - assertEquals(sensorStatistics.getAvgHeartRate(), stats.avgHr, 0f); - assertEquals(sensorStatistics.getMaxHeartRate(), stats.maxHr, 0f); - assertEquals(sensorStatistics.getAvgCadence(), stats.avgCadence, 0f); - assertEquals(sensorStatistics.getMaxCadence(), stats.maxCadence, 0f); - assertEquals(sensorStatistics.getAvgPower(), stats.avgPower, 0f); + assertEquals(sensorStatistics.getAvgHeartRate().getBPM(), stats.avgHr, 0f); + assertEquals(sensorStatistics.getMaxHeartRate().getBPM(), stats.maxHr, 0f); + assertEquals(sensorStatistics.getAvgCadence().getRPM(), stats.avgCadence, 0f); + assertEquals(sensorStatistics.getMaxCadence().getRPM(), stats.maxCadence, 0f); + assertEquals(sensorStatistics.getAvgPower().getW(), stats.avgPower, 0f); } @Test @@ -1187,11 +1189,11 @@ public class CustomContentProviderUtilsTest { TestSensorDataUtil.SensorDataStats stats = sensorDataUtil.computeStats(); // then - assertEquals(sensorStatistics.getAvgHeartRate(), stats.avgHr, 0f); - assertEquals(sensorStatistics.getMaxHeartRate(), stats.maxHr, 0f); - assertEquals(sensorStatistics.getAvgCadence(), stats.avgCadence, 0f); - assertEquals(sensorStatistics.getMaxCadence(), stats.maxCadence, 0f); - assertEquals(sensorStatistics.getAvgPower(), stats.avgPower, 0f); + assertEquals(sensorStatistics.getAvgHeartRate().getBPM(), stats.avgHr, 0f); + assertEquals(sensorStatistics.getMaxHeartRate().getBPM(), stats.maxHr, 0f); + assertEquals(sensorStatistics.getAvgCadence().getRPM(), stats.avgCadence, 0f); + assertEquals(sensorStatistics.getMaxCadence().getRPM(), stats.maxCadence, 0f); + assertEquals(sensorStatistics.getAvgPower().getW(), stats.avgPower, 0f); } private void testGetSensorStats_randomData(int totalPoints, boolean withStartSegments) { @@ -1218,11 +1220,11 @@ public class CustomContentProviderUtilsTest { TestSensorDataUtil.SensorDataStats stats = sensorDataUtil.computeStats(); // then - assertEquals(sensorStatistics.getAvgHeartRate(), stats.avgHr, 0.01f); - assertEquals(sensorStatistics.getMaxHeartRate(), stats.maxHr, 0.01f); - assertEquals(sensorStatistics.getAvgCadence(), stats.avgCadence, 0.01f); - assertEquals(sensorStatistics.getMaxCadence(), stats.maxCadence, 0.01f); - assertEquals(sensorStatistics.getAvgPower(), stats.avgPower, 0.01f); + assertEquals(sensorStatistics.getAvgHeartRate().getBPM(), stats.avgHr, 0.01f); + assertEquals(sensorStatistics.getMaxHeartRate().getBPM(), stats.maxHr, 0.01f); + assertEquals(sensorStatistics.getAvgCadence().getRPM(), stats.avgCadence, 0.01f); + assertEquals(sensorStatistics.getMaxCadence().getRPM(), stats.maxCadence, 0.01f); + assertEquals(sensorStatistics.getAvgPower().getW(), stats.avgPower, 0.01f); } @Test diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java index 38c6ab066..57c14d512 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -40,8 +40,11 @@ import java.util.concurrent.TimeoutException; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.data.ContentProviderUtils; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Marker; +import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; @@ -336,9 +339,9 @@ public class ExportImportTest { .setAltitudeLoss(1f) .setAltitudeGain(1f) .setSensorDistance(Distance.of(12)) - .setHeartRate_bpm(66f) + .setHeartRate(66f) .setPower(50f) - .setCadence_rpm(3f), + .setCadence(3f), new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, Instant.parse("2020-02-02T02:02:21Z")) .setLatitude(3) .setLongitude(14.002) @@ -439,18 +442,18 @@ public class ExportImportTest { } } - private void mockBLESensorData(TrackPointCreator trackPointCreator, Float speed, Distance distance, Float heartRate, Float cyclingCadence, Float power) { + private void mockBLESensorData(TrackPointCreator trackPointCreator, Float speed, Distance distance, float heartRate, float cadence, Float power) { trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, trackPointCreator) { @Override public SensorDataSet fill(@NonNull TrackPoint trackPoint) { SensorDataSet sensorDataSet = new SensorDataSet(); - sensorDataSet.set(new SensorDataCyclingPower("power", "power", power)); - sensorDataSet.set(new SensorDataHeartRate("heartRate", "heartRate", heartRate)); + sensorDataSet.set(new SensorDataCyclingPower("power", "power", Power.of(power))); + sensorDataSet.set(new SensorDataHeartRate("heartRate", "heartRate", HeartRate.of(heartRate))); - SensorDataCycling.Cadence cadence = Mockito.mock(SensorDataCycling.Cadence.class); - Mockito.when(cadence.hasValue()).thenReturn(true); - Mockito.when(cadence.getValue()).thenReturn(cyclingCadence); - sensorDataSet.set(cadence); + SensorDataCycling.CyclingCadence cyclingCadence = Mockito.mock(SensorDataCycling.CyclingCadence.class); + Mockito.when(cyclingCadence.hasValue()).thenReturn(true); + Mockito.when(cyclingCadence.getValue()).thenReturn(Cadence.of(cadence)); + sensorDataSet.set(cyclingCadence); if (distance != null && speed != null) { SensorDataCycling.DistanceSpeed.Data distanceSpeedData = Mockito.mock(SensorDataCycling.DistanceSpeed.Data.class); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java index 3f0eb62f9..1d5788c36 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java @@ -61,17 +61,17 @@ public class TrackPointAssert { Assert.assertEquals(expected.hasHeartRate(), actual.hasHeartRate()); if (expected.hasHeartRate()) { - Assert.assertEquals(expected.getHeartRate_bpm(), actual.getHeartRate_bpm(), delta); + Assert.assertEquals(expected.getHeartRate(), actual.getHeartRate()); } Assert.assertEquals(expected.hasPower(), actual.hasPower()); if (expected.hasPower()) { - Assert.assertEquals(expected.getPower(), actual.getPower(), delta); + Assert.assertEquals(expected.getPower(), actual.getPower()); } Assert.assertEquals(expected.hasCadence(), actual.hasCadence()); if (expected.hasCadence()) { - Assert.assertEquals(expected.getCadence_rpm(), actual.getCadence_rpm(), delta); + Assert.assertEquals(expected.getCadence(), actual.getCadence()); } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothUtilsTest.java index fa8ec1ed5..01a5a8828 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothUtilsTest.java @@ -7,6 +7,7 @@ import android.bluetooth.BluetoothGattCharacteristic; import org.junit.Test; +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.sensorData.SensorDataCycling; @@ -101,7 +102,7 @@ public class BluetoothUtilsTest { // then assertEquals(Speed.of(5), sensor.getSpeed()); - assertEquals(80, sensor.getCadence(), 0.01); + assertEquals(Cadence.of(80), sensor.getCadence()); assertEquals(Distance.of(6553.5 + 1677721.6), sensor.getTotalDistance()); } } \ 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 3fcde407f..90352ff1b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java @@ -11,6 +11,7 @@ import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.sensors.UintUtils; @@ -20,48 +21,48 @@ public class SensorDataCyclingTest { @Test public void compute_cadence_1() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024); // 1s - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 2048); // 2s + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 1, 1024); // 1s + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 2, 2048); // 2s // when current.compute(previous); // then - assertEquals(60, current.getValue(), 0.01); + assertEquals(60, current.getValue().getRPM(), 0.01); } @Test public void compute_cadence_2() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 6184); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 8016); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 1, 6184); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 2, 8016); // when current.compute(previous); // then - assertEquals(33.53, current.getValue(), 0.01); + assertEquals(33.53, current.getValue().getRPM(), 0.01); } @Test public void compute_cadence_sameCount() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 2048); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 1, 1024); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 1, 2048); // when current.compute(previous); // then - assertEquals(0, current.getValue(), 0.01); + assertEquals(Cadence.of(0), current.getValue()); } @Test public void compute_cadence_sameTime() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, 1024); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 1024); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 1, 1024); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 2, 1024); // when current.compute(previous); @@ -73,14 +74,14 @@ public class SensorDataCyclingTest { @Test public void compute_cadence_rollOverTime() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 1, UintUtils.UINT16_MAX - 1024); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 2, 0); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 1, UintUtils.UINT16_MAX - 1024); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 2, 0); // when current.compute(previous); // then - assertEquals(60, current.getValue(), 0.01); + assertEquals(60, current.getValue().getRPM(), 0.01); } @Ignore("Disabled from #953") @@ -88,21 +89,21 @@ public class SensorDataCyclingTest { @Deprecated public void compute_cadence_rollOverCount() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 0, 2048); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 0, 2048); // when current.compute(previous); // then - assertEquals(60, current.getValue(), 0.01); + assertEquals(60, current.getValue().getRPM(), 0.01); } @Test public void compute_cadence_overflow() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 0, 2048); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 0, 2048); // when current.compute(previous); @@ -171,8 +172,8 @@ public class SensorDataCyclingTest { @Test public void equals_cadence_with_no_data() { // given - SensorDataCycling.Cadence previous = new SensorDataCycling.Cadence("sensorAddress"); - SensorDataCycling.Cadence current = new SensorDataCycling.Cadence("sensorAddress", "sensorName", 0, 2048); + SensorDataCycling.CyclingCadence previous = new SensorDataCycling.CyclingCadence("sensorAddress"); + SensorDataCycling.CyclingCadence current = new SensorDataCycling.CyclingCadence("sensorAddress", "sensorName", 0, 2048); // when previous.toString(); diff --git a/src/androidTest/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilderTest.java b/src/androidTest/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilderTest.java index 56ec4163d..4e824a2c1 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilderTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilderTest.java @@ -17,7 +17,10 @@ import java.time.Duration; import java.util.List; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.HeartRate; +import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.stats.SensorStatistics; @@ -124,8 +127,8 @@ public class StatisticDataBuilderTest extends TestCase { @Test public void testFromSensorStatistics_onlyHeartRate() { when(sensorStatisticsMock.hasHeartRate()).thenReturn(true); - when(sensorStatisticsMock.getMaxHeartRate()).thenReturn(200f); - when(sensorStatisticsMock.getAvgHeartRate()).thenReturn(150f); + when(sensorStatisticsMock.getMaxHeartRate()).thenReturn(HeartRate.of(200f)); + when(sensorStatisticsMock.getAvgHeartRate()).thenReturn(HeartRate.of(150f)); when(sensorStatisticsMock.hasCadence()).thenReturn(false); when(sensorStatisticsMock.hasPower()).thenReturn(false); @@ -142,8 +145,8 @@ public class StatisticDataBuilderTest extends TestCase { public void testFromSensorStatistics_onlyCadence() { when(sensorStatisticsMock.hasHeartRate()).thenReturn(false); when(sensorStatisticsMock.hasCadence()).thenReturn(true); - when(sensorStatisticsMock.getAvgCadence()).thenReturn(90f); - when(sensorStatisticsMock.getMaxCadence()).thenReturn(110f); + when(sensorStatisticsMock.getAvgCadence()).thenReturn(Cadence.of(90f)); + when(sensorStatisticsMock.getMaxCadence()).thenReturn(Cadence.of(110f)); when(sensorStatisticsMock.hasPower()).thenReturn(false); // when @@ -160,7 +163,7 @@ public class StatisticDataBuilderTest extends TestCase { when(sensorStatisticsMock.hasHeartRate()).thenReturn(false); when(sensorStatisticsMock.hasCadence()).thenReturn(false); when(sensorStatisticsMock.hasPower()).thenReturn(true); - when(sensorStatisticsMock.getAvgPower()).thenReturn(300f); + when(sensorStatisticsMock.getAvgPower()).thenReturn(Power.of(300f)); // when List statisticDataList = StatisticDataBuilder.fromSensorStatistics(context, sensorStatisticsMock); @@ -173,13 +176,13 @@ public class StatisticDataBuilderTest extends TestCase { @Test public void testFromSensorStatistics() { when(sensorStatisticsMock.hasHeartRate()).thenReturn(true); - when(sensorStatisticsMock.getMaxHeartRate()).thenReturn(200f); - when(sensorStatisticsMock.getAvgHeartRate()).thenReturn(150f); + when(sensorStatisticsMock.getMaxHeartRate()).thenReturn(HeartRate.of(200f)); + when(sensorStatisticsMock.getAvgHeartRate()).thenReturn(HeartRate.of(150f)); when(sensorStatisticsMock.hasCadence()).thenReturn(true); - when(sensorStatisticsMock.getAvgCadence()).thenReturn(90f); - when(sensorStatisticsMock.getMaxCadence()).thenReturn(110f); + when(sensorStatisticsMock.getAvgCadence()).thenReturn(Cadence.of(90f)); + when(sensorStatisticsMock.getMaxCadence()).thenReturn(Cadence.of(110f)); when(sensorStatisticsMock.hasPower()).thenReturn(true); - when(sensorStatisticsMock.getAvgPower()).thenReturn(300f); + when(sensorStatisticsMock.getAvgPower()).thenReturn(Power.of(300f)); // when List statisticDataList = StatisticDataBuilder.fromSensorStatistics(context, sensorStatisticsMock); diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java b/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java index a84d89f88..1cd365678 100644 --- a/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java +++ b/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java @@ -44,13 +44,13 @@ public class ChartPoint { pace = smoothedSpeed.toPace(metricUnits).toMillis() * UnitConversions.MS_TO_S * UnitConversions.S_TO_MIN; } if (trackPoint.hasHeartRate()) { - heartRate = (double) trackPoint.getHeartRate_bpm(); + heartRate = (double) trackPoint.getHeartRate().getBPM(); } if (trackPoint.hasCadence()) { - cadence = (double) trackPoint.getCadence_rpm(); + cadence = (double) trackPoint.getCadence().getRPM(); } if (trackPoint.hasPower()) { - power = (double) trackPoint.getPower(); + power = (double) trackPoint.getPower().getW(); } } diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index ba1940076..ebb110c45 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -41,8 +41,11 @@ import java.util.UUID; import de.dennisguse.opentracks.BuildConfig; import de.dennisguse.opentracks.data.models.Altitude; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Marker; +import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; @@ -577,10 +580,10 @@ public class ContentProviderUtils { } if (!cursor.isNull(indexes.sensorHeartRateIndex)) { - trackPoint.setHeartRate_bpm(cursor.getFloat(indexes.sensorHeartRateIndex)); + trackPoint.setHeartRate(cursor.getFloat(indexes.sensorHeartRateIndex)); } if (!cursor.isNull(indexes.sensorCadenceIndex)) { - trackPoint.setCadence_rpm(cursor.getFloat(indexes.sensorCadenceIndex)); + trackPoint.setCadence(cursor.getFloat(indexes.sensorCadenceIndex)); } if (!cursor.isNull(indexes.sensorDistanceIndex)) { trackPoint.setSensorDistance(Distance.of(cursor.getFloat(indexes.sensorDistanceIndex))); @@ -739,16 +742,16 @@ public class ContentProviderUtils { } if (trackPoint.hasHeartRate()) { - values.put(TrackPointsColumns.SENSOR_HEARTRATE, trackPoint.getHeartRate_bpm()); + values.put(TrackPointsColumns.SENSOR_HEARTRATE, trackPoint.getHeartRate().getBPM()); } if (trackPoint.hasCadence()) { - values.put(TrackPointsColumns.SENSOR_CADENCE, trackPoint.getCadence_rpm()); + values.put(TrackPointsColumns.SENSOR_CADENCE, trackPoint.getCadence().getRPM()); } if (trackPoint.hasSensorDistance()) { values.put(TrackPointsColumns.SENSOR_DISTANCE, trackPoint.getSensorDistance().toM()); } if (trackPoint.hasPower()) { - values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getPower()); + values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getPower().getW()); } if (trackPoint.hasAltitudeGain()) { @@ -831,12 +834,17 @@ public class ContentProviderUtils { SensorStatistics sensorStatistics = null; try (Cursor cursor = contentResolver.query(ContentUris.withAppendedId(TracksColumns.CONTENT_URI_SENSOR_STATS, trackId.getId()), null, null, null, null)) { if (cursor != null && cursor.moveToFirst()) { + final int MAX_HR_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_MAX_HR); + final int AVG_HR_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_HR); + final int MAX_CADENCE_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_MAX_CADENCE); + final int AVG_CADENCE_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_CADENCE); + final int AVG_POWER_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_POWER); sensorStatistics = new SensorStatistics( - !cursor.isNull(cursor.getColumnIndexOrThrow("max_hr")) ? cursor.getFloat(cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_MAX_HR)) : null, - !cursor.isNull(cursor.getColumnIndexOrThrow("avg_hr")) ? cursor.getFloat(cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_HR)) : null, - !cursor.isNull(cursor.getColumnIndexOrThrow("max_cadence")) ? cursor.getFloat(cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_MAX_CADENCE)) : null, - !cursor.isNull(cursor.getColumnIndexOrThrow("avg_cadence")) ? cursor.getFloat(cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_CADENCE)) : null, - !cursor.isNull(cursor.getColumnIndexOrThrow("avg_power")) ? cursor.getFloat(cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_POWER)) : null + !cursor.isNull(MAX_HR_INDEX) ? HeartRate.of(cursor.getFloat(MAX_HR_INDEX)) : null, + !cursor.isNull(AVG_HR_INDEX) ? HeartRate.of(cursor.getFloat(AVG_HR_INDEX)) : null, + !cursor.isNull(MAX_CADENCE_INDEX) ? Cadence.of(cursor.getFloat(MAX_CADENCE_INDEX)) : null, + !cursor.isNull(AVG_CADENCE_INDEX) ? Cadence.of(cursor.getFloat(AVG_CADENCE_INDEX)) : null, + !cursor.isNull(AVG_POWER_INDEX) ? Power.of(cursor.getFloat(AVG_POWER_INDEX)) : null ); } diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Cadence.java b/src/main/java/de/dennisguse/opentracks/data/models/Cadence.java new file mode 100644 index 000000000..fcf3c7155 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/data/models/Cadence.java @@ -0,0 +1,43 @@ +package de.dennisguse.opentracks.data.models; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +public class Cadence { + + public static Cadence of(float value) { + return new Cadence(value); + } + + private final float value; + + private Cadence(float value) { + this.value = value; + } + + public float getRPM() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Cadence cadence = (Cadence) o; + return Float.compare(cadence.value, value) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @NonNull + @Override + public String toString() { + return "Cadence{" + + "value=" + value + " rpm" + + '}'; + } +} diff --git a/src/main/java/de/dennisguse/opentracks/data/models/HeartRate.java b/src/main/java/de/dennisguse/opentracks/data/models/HeartRate.java new file mode 100644 index 000000000..085b00481 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/data/models/HeartRate.java @@ -0,0 +1,43 @@ +package de.dennisguse.opentracks.data.models; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +public class HeartRate { + + public static HeartRate of(float value) { + return new HeartRate(value); + } + + private final float value; + + private HeartRate(float value) { + this.value = value; + } + + public float getBPM() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + HeartRate heartRate = (HeartRate) o; + return Float.compare(heartRate.value, value) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @NonNull + @Override + public String toString() { + return "HeartRate{" + + "value=" + value + " bpm" + + '}'; + } +} diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Power.java b/src/main/java/de/dennisguse/opentracks/data/models/Power.java new file mode 100644 index 000000000..52c2cebab --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/data/models/Power.java @@ -0,0 +1,43 @@ +package de.dennisguse.opentracks.data.models; + +import androidx.annotation.NonNull; + +import java.util.Objects; + +public class Power { + + public static Power of(float value) { + return new Power(value); + } + + private final float value; + + private Power(float value) { + this.value = value; + } + + public float getW() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Power power = (Power) o; + return Float.compare(power.value, value) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @NonNull + @Override + public String toString() { + return "Power{" + + "value=" + value + " W" + + '}'; + } +} diff --git a/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java index 82f1ca03d..c993cfcac 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java @@ -91,9 +91,9 @@ public class TrackPoint { @NonNull private Type type; - private Float heartRate_bpm = null; - private Float cadence_rpm = null; - private Float power = null; + private HeartRate heartRate = null; + private Cadence cadence = null; + private Power power = null; private Float altitudeGain_m = null; private Float altitudeLoss_m = null; @@ -382,44 +382,56 @@ public class TrackPoint { } public boolean hasHeartRate() { - return heartRate_bpm != null && heartRate_bpm > 0; + return heartRate != null; } - public float getHeartRate_bpm() { - return heartRate_bpm; + public HeartRate getHeartRate() { + return heartRate; } - public TrackPoint setHeartRate_bpm(Float heartRate_bpm) { - this.heartRate_bpm = heartRate_bpm; + public TrackPoint setHeartRate(HeartRate heartRate) { + this.heartRate = heartRate; return this; } + public TrackPoint setHeartRate(float heartRate) { + return setHeartRate(HeartRate.of(heartRate)); + } + public boolean hasCadence() { - return cadence_rpm != null; + return cadence != null; } - public float getCadence_rpm() { - return cadence_rpm; + public Cadence getCadence() { + return cadence; } - public TrackPoint setCadence_rpm(Float cadence_rpm) { - this.cadence_rpm = cadence_rpm; + public TrackPoint setCadence(Cadence cadence) { + this.cadence = cadence; return this; } + public TrackPoint setCadence(float cadence) { + return setCadence(Cadence.of(cadence)); + } + public boolean hasPower() { return power != null; } - public float getPower() { + public Power getPower() { return power; } - public TrackPoint setPower(Float power) { + public TrackPoint setPower(Power power) { this.power = power; return this; } + public TrackPoint setPower(float power) { + return setPower(Power.of(power)); + } + @NonNull @Override public String toString() { @@ -434,8 +446,8 @@ public class TrackPoint { ", bearing=" + bearing + ", sensorDistance=" + sensorDistance + ", type=" + type + - ", heartRate_bpm=" + heartRate_bpm + - ", cadence_rpm=" + cadence_rpm + + ", heartRate_bpm=" + heartRate + + ", cadence_rpm=" + cadence + ", power=" + power + ", altitudeGain_m=" + altitudeGain_m + ", altitudeLoss_m=" + altitudeLoss_m + diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index 737ac081f..cbd0675d0 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -331,15 +331,15 @@ public class GPXTrackExporter implements TrackExporter { } if (trackPoint.hasHeartRate()) { - trackPointExtensionContent += "" + HEARTRATE_FORMAT.format(trackPoint.getHeartRate_bpm()) + "\n"; + trackPointExtensionContent += "" + HEARTRATE_FORMAT.format(trackPoint.getHeartRate().getBPM()) + "\n"; } if (trackPoint.hasCadence()) { - trackPointExtensionContent += "" + CADENCE_FORMAT.format(trackPoint.getCadence_rpm()) + "\n"; + trackPointExtensionContent += "" + CADENCE_FORMAT.format(trackPoint.getCadence().getRPM()) + "\n"; } if (trackPoint.hasPower()) { - trackPointExtensionContent += "" + POWER_FORMAT.format(trackPoint.getPower()) + "\n"; + trackPointExtensionContent += "" + POWER_FORMAT.format(trackPoint.getPower().getW()) + "\n"; } Double cumulativeGain = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeGain() ? (double) tp.getAltitudeGain() : null); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java index 90bb43aaa..e11b23065 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java @@ -381,9 +381,9 @@ public class KMLTrackExporter implements TrackExporter { speedList.add(trackPoint.hasSpeed() ? (float) trackPoint.getSpeed().toMPS() : null); distanceList.add(trackPoint.hasSensorDistance() ? (float) trackPoint.getSensorDistance().toM() : null); - heartRateList.add(trackPoint.hasHeartRate() ? trackPoint.getHeartRate_bpm() : null); - cadenceList.add(trackPoint.hasCadence() ? trackPoint.getCadence_rpm() : null); - powerList.add(trackPoint.hasPower() ? trackPoint.getPower() : null); + heartRateList.add(trackPoint.hasHeartRate() ? trackPoint.getHeartRate().getBPM() : null); + cadenceList.add(trackPoint.hasCadence() ? trackPoint.getCadence().getRPM() : null); + powerList.add(trackPoint.hasPower() ? trackPoint.getPower().getW() : null); altitudeGainList.add(trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : null); altitudeLossList.add(trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : null); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxTrackImporter.java index d3b17a5fe..d98d80ea2 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxTrackImporter.java @@ -299,7 +299,7 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac } if (heartrate != null) { try { - trackPoint.setHeartRate_bpm(Float.parseFloat(heartrate)); + trackPoint.setHeartRate(Float.parseFloat(heartrate)); } catch (NumberFormatException e) { throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse heart rate: %s", heartrate)), e); } @@ -307,7 +307,7 @@ public class GpxTrackImporter extends DefaultHandler implements XMLImporter.Trac if (cadence != null) { try { - trackPoint.setCadence_rpm(Float.parseFloat(cadence)); + trackPoint.setCadence(Float.parseFloat(cadence)); } catch (Exception e) { throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse cadence: %s", cadence)), e); } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlTrackImporter.java index 3c7eb14c7..52ba30e28 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlTrackImporter.java @@ -318,13 +318,13 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac if (i < sensorDistanceList.size() && sensorDistanceList.get(i) != null) { trackPoint.setSensorDistance(Distance.of(sensorDistanceList.get(i))); } - if (i < sensorHeartRateList.size()) { - trackPoint.setHeartRate_bpm(sensorHeartRateList.get(i)); + if (i < sensorHeartRateList.size() && sensorHeartRateList.get(i) != null) { + trackPoint.setHeartRate(sensorHeartRateList.get(i)); } - if (i < sensorCadenceList.size()) { - trackPoint.setCadence_rpm(sensorCadenceList.get(i)); + if (i < sensorCadenceList.size() && sensorCadenceList.get(i) != null) { + trackPoint.setCadence(sensorCadenceList.get(i)); } - if (i < sensorPowerList.size()) { + if (i < sensorPowerList.size() && sensorPowerList.get(i) != null) { trackPoint.setPower(sensorPowerList.get(i)); } if (i < altitudeGainList.size()) { diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java index 3a7969b52..2c55cac04 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java @@ -30,6 +30,9 @@ import androidx.annotation.NonNull; import java.util.UUID; +import de.dennisguse.opentracks.data.models.Cadence; +import de.dennisguse.opentracks.data.models.HeartRate; +import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.sensors.sensorData.SensorData; import de.dennisguse.opentracks.sensors.sensorData.SensorDataCycling; import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingPower; @@ -161,9 +164,9 @@ public abstract class BluetoothConnectionManager { */ protected abstract SensorData parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic); - public static class HeartRate extends BluetoothConnectionManager { + public static class HeartRateConnectionManager extends BluetoothConnectionManager { - HeartRate(@NonNull SensorDataObserver observer) { + HeartRateConnectionManager(@NonNull SensorDataObserver observer) { super(BluetoothUtils.HEART_RATE_SERVICE_UUID, BluetoothUtils.HEART_RATE_MEASUREMENT_CHAR_UUID, observer); } @@ -176,23 +179,23 @@ public abstract class BluetoothConnectionManager { protected SensorDataHeartRate parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) { Integer heartRate = BluetoothUtils.parseHeartRate(characteristic); - return heartRate != null ? new SensorDataHeartRate(address, sensorName, heartRate) : null; + return heartRate != null ? new SensorDataHeartRate(address, sensorName, HeartRate.of(heartRate)) : null; } } - public static class CyclingCadence extends BluetoothConnectionManager { + public static class CyclingCadence extends BluetoothConnectionManager { CyclingCadence(SensorDataObserver observer) { super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID, observer); } @Override - protected SensorDataCycling.Cadence createEmptySensorData(String address) { - return new SensorDataCycling.Cadence(address); + protected SensorDataCycling.CyclingCadence createEmptySensorData(String address) { + return new SensorDataCycling.CyclingCadence(address); } @Override - protected SensorDataCycling.Cadence parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) { + protected SensorDataCycling.CyclingCadence parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) { SensorDataCycling.CadenceAndSpeed cadenceAndSpeed = BluetoothUtils.parseCyclingCrankAndWheel(address, sensorName, characteristic); if (cadenceAndSpeed == null) { return null; @@ -232,7 +235,7 @@ public abstract class BluetoothConnectionManager { } } - public static class CyclingPower extends BluetoothConnectionManager { + public static class CyclingPower extends BluetoothConnectionManager { CyclingPower(@NonNull SensorDataObserver observer) { super(BluetoothUtils.CYCLING_POWER_UUID, BluetoothUtils.CYCLING_POWER_MEASUREMENT_CHAR_UUID, observer); @@ -247,7 +250,7 @@ public abstract class BluetoothConnectionManager { protected SensorDataCyclingPower parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) { Integer cyclingPower = BluetoothUtils.parseCyclingPower(characteristic); - return cyclingPower != null ? new SensorDataCyclingPower(address, sensorName, cyclingPower) : null; + return cyclingPower != null ? new SensorDataCyclingPower(address, sensorName, Power.of(cyclingPower)) : null; } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java index 7d67eb7a5..a9f025158 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java @@ -62,7 +62,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager. private Distance preferenceWheelCircumference; - private final BluetoothConnectionManager.HeartRate heartRate = new BluetoothConnectionManager.HeartRate(this); + private final BluetoothConnectionManager.HeartRateConnectionManager heartRate = new BluetoothConnectionManager.HeartRateConnectionManager(this); private final BluetoothConnectionManager.CyclingCadence cyclingCadence = new BluetoothConnectionManager.CyclingCadence(this); private final BluetoothConnectionManager.CyclingDistanceSpeed cyclingSpeed = new BluetoothConnectionManager.CyclingDistanceSpeed(this); private final BluetoothConnectionManager.CyclingPower cyclingPower = new BluetoothConnectionManager.CyclingPower(this); @@ -180,15 +180,15 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager. @Override public synchronized void onChanged(SensorData sensorData) { - if (sensorData instanceof SensorDataCycling.Cadence) { - SensorDataCycling.Cadence previous = sensorDataSet.getCyclingCadence(); + if (sensorData instanceof SensorDataCycling.CyclingCadence) { + SensorDataCycling.CyclingCadence previous = sensorDataSet.getCyclingCadence(); Log.d(TAG, "Previous: " + previous + "; current: " + sensorData); if (sensorData.equals(previous)) { Log.d(TAG, "onChanged: cadence data repeated."); return; } - ((SensorDataCycling.Cadence) sensorData).compute(previous); + ((SensorDataCycling.CyclingCadence) sensorData).compute(previous); } if (sensorData instanceof SensorDataCycling.DistanceSpeed) { SensorDataCycling.DistanceSpeed previous = sensorDataSet.getCyclingDistanceSpeed(); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothUtils.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothUtils.java index 5d13270c1..d3120843b 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothUtils.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothUtils.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.List; import java.util.UUID; +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.sensorData.SensorDataCycling; @@ -128,13 +129,13 @@ public class BluetoothUtils { index += 2; } - SensorDataCycling.Cadence cadence = null; + SensorDataCycling.CyclingCadence cadence = null; if (hasCrank && valueLength - index >= 4) { long crankCount = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, index); index += 2; int crankTime = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, index); // 1/1024s - cadence = new SensorDataCycling.Cadence(address, sensorName, crankCount, crankTime); + cadence = new SensorDataCycling.CyclingCadence(address, sensorName, crankCount, crankTime); } return new SensorDataCycling.CadenceAndSpeed(address, sensorName, cadence, speed); @@ -153,7 +154,7 @@ public class BluetoothUtils { boolean hasStatus = (flags & 0x03) > 0; // walking vs running Speed speed = null; - Float cadence = null; + Cadence cadence = null; Distance totalDistance = null; int index = 1; @@ -163,7 +164,7 @@ public class BluetoothUtils { index = 3; if (valueLength - index >= 1) { - cadence = Float.valueOf(characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, index)); + cadence = Cadence.of(characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, index)); } index = 4; diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCycling.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCycling.java index c94ef5bca..9337bef47 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCycling.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCycling.java @@ -8,6 +8,7 @@ import androidx.core.util.Pair; import java.time.Duration; +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.data.models.UnitConversions; @@ -23,18 +24,18 @@ public final class SensorDataCycling { private SensorDataCycling() { } - public static class Cadence extends SensorData { + public static class CyclingCadence extends SensorData { private final Long crankRevolutionsCount; // UINT32 private final Integer crankRevolutionsTime; // UINT16; 1/1024s - public Cadence(String sensorAddress) { + public CyclingCadence(String sensorAddress) { super(sensorAddress); this.crankRevolutionsCount = null; this.crankRevolutionsTime = null; } - public Cadence(String sensorAddress, String sensorName, long crankRevolutionsCount, int crankRevolutionsTime) { + public CyclingCadence(String sensorAddress, String sensorName, long crankRevolutionsCount, int crankRevolutionsTime) { super(sensorAddress, sensorName); this.crankRevolutionsCount = crankRevolutionsCount; this.crankRevolutionsTime = crankRevolutionsTime; @@ -43,7 +44,7 @@ public final class SensorDataCycling { /** * Workaround for Wahoo CADENCE: provides speed instead of cadence */ - public Cadence(@NonNull DistanceSpeed speed) { + public CyclingCadence(@NonNull DistanceSpeed speed) { this(speed.getSensorAddress(), speed.getSensorName(), speed.wheelRevolutionsCount, speed.wheelRevolutionsTime); } @@ -61,11 +62,11 @@ public final class SensorDataCycling { @NonNull @Override - protected Float getNoneValue() { - return 0f; + protected Cadence getNoneValue() { + return Cadence.of(0); } - public void compute(Cadence previous) { + public void compute(CyclingCadence previous) { if (hasData() && previous != null && previous.hasData()) { float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * UnitConversions.S_TO_MS; if (timeDiff_ms <= 0) { @@ -82,7 +83,7 @@ public final class SensorDataCycling { long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX); float cadence_ms = crankDiff / timeDiff_ms; - value = (float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN); + value = Cadence.of((float) (cadence_ms / UnitConversions.MS_TO_S / UnitConversions.S_TO_MIN)); } } @@ -94,9 +95,9 @@ public final class SensorDataCycling { @Override public boolean equals(@Nullable Object obj) { - if (!(obj instanceof Cadence)) return false; + if (!(obj instanceof CyclingCadence)) return false; - Cadence comp = (Cadence) obj; + CyclingCadence comp = (CyclingCadence) obj; if (hasData() && comp.hasData() == hasData()) { return getCrankRevolutionsCount() == comp.getCrankRevolutionsCount() && getCrankRevolutionsTime() == comp.getCrankRevolutionsTime(); } else { @@ -230,14 +231,14 @@ public final class SensorDataCycling { } } - public static class CadenceAndSpeed extends SensorData> { + public static class CadenceAndSpeed extends SensorData> { - public CadenceAndSpeed(String sensorAddress, String sensorName, @Nullable Cadence cadence, @Nullable DistanceSpeed distanceSpeed) { + public CadenceAndSpeed(String sensorAddress, String sensorName, @Nullable CyclingCadence cadence, @Nullable DistanceSpeed distanceSpeed) { super(sensorAddress, sensorName); this.value = new Pair<>(cadence, distanceSpeed); } - public Cadence getCadence() { + public CyclingCadence getCadence() { return this.value != null ? this.value.first : null; } @@ -247,7 +248,7 @@ public final class SensorDataCycling { @NonNull @Override - protected Pair getNoneValue() { + protected Pair getNoneValue() { return new Pair<>(null, null); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingPower.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingPower.java index fba7255b8..dae106132 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingPower.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingPower.java @@ -2,15 +2,17 @@ package de.dennisguse.opentracks.sensors.sensorData; import androidx.annotation.NonNull; -public class SensorDataCyclingPower extends SensorData { +import de.dennisguse.opentracks.data.models.Power; + +public class SensorDataCyclingPower extends SensorData { public SensorDataCyclingPower(String address) { super(address); } - public SensorDataCyclingPower(String name, String address, float power_w) { + public SensorDataCyclingPower(String name, String address, Power power) { super(name, address); - this.value = power_w; + this.value = power; } @NonNull @@ -21,7 +23,7 @@ public class SensorDataCyclingPower extends SensorData { @NonNull @Override - protected Float getNoneValue() { - return 0f; + protected Power getNoneValue() { + return Power.of(0f); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataHeartRate.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataHeartRate.java index ce6347ed2..3f02eca7d 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataHeartRate.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataHeartRate.java @@ -2,15 +2,17 @@ package de.dennisguse.opentracks.sensors.sensorData; import androidx.annotation.NonNull; -public class SensorDataHeartRate extends SensorData { +import de.dennisguse.opentracks.data.models.HeartRate; + +public class SensorDataHeartRate extends SensorData { public SensorDataHeartRate(String address) { super(address); } - public SensorDataHeartRate(String name, String address, float heartRate_bpm) { + public SensorDataHeartRate(String name, String address, @NonNull HeartRate heartRate) { super(name, address); - this.value = heartRate_bpm; + this.value = heartRate; } @NonNull @@ -21,7 +23,7 @@ public class SensorDataHeartRate extends SensorData { @NonNull @Override - protected Float getNoneValue() { - return 0f; + protected HeartRate getNoneValue() { + return HeartRate.of(0); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataRunning.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataRunning.java index 61fa80b43..5e3c1000d 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataRunning.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataRunning.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; @@ -16,7 +17,7 @@ public final class SensorDataRunning extends SensorData private final Speed speed; - private final Float cadence; + private final Cadence cadence; private final Distance totalDistance; @@ -27,7 +28,7 @@ public final class SensorDataRunning extends SensorData this.totalDistance = null; } - public SensorDataRunning(String sensorAddress, String sensorName, Speed speed, Float cadence, Distance totalDistance) { + public SensorDataRunning(String sensorAddress, String sensorName, Speed speed, Cadence cadence, Distance totalDistance) { super(sensorAddress, sensorName); this.speed = speed; this.cadence = cadence; @@ -39,7 +40,7 @@ public final class SensorDataRunning extends SensorData } - public Float getCadence() { + public Cadence getCadence() { return cadence; } @@ -56,9 +57,9 @@ public final class SensorDataRunning extends SensorData @Override protected Data getNoneValue() { if (value != null) { - return new Data(Speed.zero(), 0f, value.distance); + return new Data(Speed.zero(), Cadence.of(0f), value.distance); } else { - return new Data(Speed.zero(), 0f, Distance.of(0)); + return new Data(Speed.zero(), Cadence.of(0f), Distance.of(0)); } } @@ -85,12 +86,12 @@ public final class SensorDataRunning extends SensorData public static class Data { private final Speed speed; - private final Float cadence; + private final Cadence cadence; @Nullable private final Distance distance; - public Data(Speed speed, Float cadence, @Nullable Distance distance) { + public Data(Speed speed, Cadence cadence, @Nullable Distance distance) { this.speed = speed; this.cadence = cadence; this.distance = distance; @@ -100,7 +101,7 @@ public final class SensorDataRunning extends SensorData return speed; } - public Float getCadence() { + public Cadence getCadence() { return cadence; } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java index c4764c2f5..e054f2c2e 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java @@ -4,6 +4,8 @@ import android.util.Pair; import androidx.annotation.NonNull; +import de.dennisguse.opentracks.data.models.Cadence; +import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.TrackPoint; @@ -11,7 +13,7 @@ public final class SensorDataSet { private SensorDataHeartRate heartRate; - private SensorDataCycling.Cadence cyclingCadence; + private SensorDataCycling.CyclingCadence cyclingCadence; private SensorDataCycling.DistanceSpeed cyclingDistanceSpeed; @@ -30,7 +32,7 @@ public final class SensorDataSet { this.runningDistanceSpeedCadence = toCopy.runningDistanceSpeedCadence; } - public Pair getHeartRate() { + public Pair getHeartRate() { if (heartRate != null) { return new Pair<>(heartRate.getValue(), heartRate.getSensorNameOrAddress()); } @@ -38,7 +40,7 @@ public final class SensorDataSet { return null; } - public Pair getCadence() { + public Pair getCadence() { if (cyclingCadence != null) { return new Pair<>(cyclingCadence.getValue(), cyclingCadence.getSensorNameOrAddress()); } @@ -62,7 +64,7 @@ public final class SensorDataSet { return null; } - public SensorDataCycling.Cadence getCyclingCadence() { + public SensorDataCycling.CyclingCadence getCyclingCadence() { return cyclingCadence; } @@ -96,11 +98,11 @@ public final class SensorDataSet { public void fillTrackPoint(TrackPoint trackPoint) { if (getHeartRate() != null) { - trackPoint.setHeartRate_bpm(getHeartRate().first); + trackPoint.setHeartRate(getHeartRate().first); } if (getCadence() != null) { - trackPoint.setCadence_rpm(getCadence().first); + trackPoint.setCadence(getCadence().first); } if (getSpeed() != null) { @@ -144,8 +146,8 @@ public final class SensorDataSet { return; } - if (type instanceof SensorDataCycling.Cadence) { - this.cyclingCadence = (SensorDataCycling.Cadence) data; + if (type instanceof SensorDataCycling.CyclingCadence) { + this.cyclingCadence = (SensorDataCycling.CyclingCadence) data; return; } if (type instanceof SensorDataCycling.DistanceSpeed) { diff --git a/src/main/java/de/dennisguse/opentracks/stats/SensorStatistics.java b/src/main/java/de/dennisguse/opentracks/stats/SensorStatistics.java index 46b043f2d..4ca4ee320 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SensorStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SensorStatistics.java @@ -1,13 +1,17 @@ package de.dennisguse.opentracks.stats; -public class SensorStatistics { - private final Float maxHr; - private final Float avgHr; - private final Float maxCadence; - private final Float avgCadence; - private final Float avgPower; +import de.dennisguse.opentracks.data.models.Cadence; +import de.dennisguse.opentracks.data.models.HeartRate; +import de.dennisguse.opentracks.data.models.Power; - public SensorStatistics(Float maxHr, Float avgHr, Float maxCadence, Float avgCadence, Float avgPower) { +public class SensorStatistics { + private final HeartRate maxHr; + private final HeartRate avgHr; + private final Cadence maxCadence; + private final Cadence avgCadence; + private final Power avgPower; + + public SensorStatistics(HeartRate maxHr, HeartRate avgHr, Cadence maxCadence, Cadence avgCadence, Power avgPower) { this.maxHr = maxHr; this.avgHr = avgHr; this.maxCadence = maxCadence; @@ -19,11 +23,11 @@ public class SensorStatistics { return avgHr != null && maxHr != null; } - public float getMaxHeartRate() { + public HeartRate getMaxHeartRate() { return maxHr; } - public float getAvgHeartRate() { + public HeartRate getAvgHeartRate() { return avgHr; } @@ -31,11 +35,11 @@ public class SensorStatistics { return avgCadence != null && maxCadence != null; } - public float getMaxCadence() { + public Cadence getMaxCadence() { return maxCadence; } - public float getAvgCadence() { + public Cadence getAvgCadence() { return avgCadence; } @@ -43,7 +47,7 @@ public class SensorStatistics { return avgPower != null; } - public float getAvgPower() { + public Power getAvgPower() { return avgPower; } } diff --git a/src/main/java/de/dennisguse/opentracks/util/StringUtils.java b/src/main/java/de/dennisguse/opentracks/util/StringUtils.java index 25592ec01..83ffb8e36 100644 --- a/src/main/java/de/dennisguse/opentracks/util/StringUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/StringUtils.java @@ -41,7 +41,10 @@ import java.time.format.FormatStyle; import java.time.temporal.TemporalAccessor; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.HeartRate; +import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; /** @@ -245,28 +248,28 @@ public class StringUtils { return new Pair<>(context.getString(R.string.time, minutes, seconds), unitString); } - public static Pair getHeartRateParts(Context context, Float heartrate_bpm) { + public static Pair getHeartRateParts(Context context, HeartRate heartrate) { String value = context.getString(R.string.value_unknown); - if (heartrate_bpm != null) { - value = StringUtils.formatDecimal(heartrate_bpm, 0); + if (heartrate != null) { + value = StringUtils.formatDecimal(heartrate.getBPM(), 0); } return new Pair<>(value, context.getString(R.string.sensor_unit_beats_per_minute)); } - public static Pair getCadenceParts(Context context, Float cadence_rpm) { + public static Pair getCadenceParts(Context context, Cadence cadence) { String value = context.getString(R.string.value_unknown); - if (cadence_rpm != null) { - value = StringUtils.formatDecimal(cadence_rpm, 0); + if (cadence != null) { + value = StringUtils.formatDecimal(cadence.getRPM(), 0); } return new Pair<>(value, context.getString(R.string.sensor_unit_rounds_per_minute)); } - public static Pair getPowerParts(Context context, Float power_w) { + public static Pair getPowerParts(Context context, Power power) { String value = context.getString(R.string.value_unknown); - if (power_w != null) { - value = StringUtils.formatDecimal(power_w, 0); + if (power != null) { + value = StringUtils.formatDecimal(power.getW(), 0); } return new Pair<>(value, context.getString(R.string.sensor_unit_power)); diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilder.java b/src/main/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilder.java index c7de147a3..a619c4205 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilder.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/StatisticDataBuilder.java @@ -11,6 +11,7 @@ import java.util.Objects; import java.util.stream.Collectors; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; @@ -115,9 +116,9 @@ public class StatisticDataBuilder { } else if (fieldKey.equals(context.getString(R.string.stats_custom_layout_cadence_key))) { title = context.getString(R.string.stats_sensors_cadence); - Float cadence = null; + Cadence cadence = null; if (sensorDataSet != null) { - Pair cadenceData = sensorDataSet.getCadence(); + Pair cadenceData = sensorDataSet.getCadence(); if (cadenceData != null) { cadence = cadenceData.first; description = cadenceData.second;