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 7065be17d..e2966bcf7 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 @@ -548,22 +548,28 @@ public class ExportImportTest { private void mockBLESensorData(TrackPointCreator trackPointCreator, Float speed, Distance distance, float heartRate, float cadence, Float power) { SensorDataSet sensorDataSet = new SensorDataSet(); - sensorDataSet.set(new SensorDataCyclingPower("power", "power", Power.of(power))); - sensorDataSet.set(new SensorDataHeartRate("heartRate", "heartRate", HeartRate.of(heartRate))); + + sensorDataSet.cyclingPower = Mockito.mock(SensorDataCyclingPower.class); + Mockito.when( sensorDataSet.cyclingPower.hasValue()).thenReturn(true); + Mockito.when(sensorDataSet.cyclingPower.getValue()).thenReturn(Power.of(power)); + + sensorDataSet.heartRate = Mockito.mock(SensorDataHeartRate.class); + Mockito.when(sensorDataSet.heartRate.getValue()).thenReturn(HeartRate.of(heartRate)); SensorDataCyclingCadence cyclingCadence = Mockito.mock(SensorDataCyclingCadence.class); Mockito.when(cyclingCadence.hasValue()).thenReturn(true); Mockito.when(cyclingCadence.getValue()).thenReturn(Cadence.of(cadence)); - sensorDataSet.set(cyclingCadence); + sensorDataSet.cyclingCadence = cyclingCadence; if (distance != null && speed != null) { SensorDataCyclingDistanceSpeed.Data distanceSpeedData = Mockito.mock(SensorDataCyclingDistanceSpeed.Data.class); Mockito.when(distanceSpeedData.getDistanceOverall()).thenReturn(distance); Mockito.when(distanceSpeedData.getSpeed()).thenReturn(Speed.of(speed)); + SensorDataCyclingDistanceSpeed distanceSpeed = Mockito.mock(SensorDataCyclingDistanceSpeed.class); Mockito.when(distanceSpeed.hasValue()).thenReturn(true); Mockito.when(distanceSpeed.getValue()).thenReturn(distanceSpeedData); - sensorDataSet.set(distanceSpeed); + sensorDataSet.cyclingDistanceSpeed = distanceSpeed; } trackPointCreator.getSensorManager().sensorDataSet = sensorDataSet; diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeedTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeedTest.java index 40e515920..58bbbfacd 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeedTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeedTest.java @@ -4,11 +4,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import android.bluetooth.BluetoothGattCharacteristic; +import android.util.Pair; import org.junit.Test; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadenceAndDistanceSpeed; - public class BluetoothHandlerCyclingDistanceSpeedTest { @Test public void parseCyclingSpeedCadence_crankOnly() { @@ -16,11 +15,11 @@ public class BluetoothHandlerCyclingDistanceSpeedTest { characteristic.setValue(new byte[]{0x02, (byte) 0xC8, 0x00, 0x00, 0x00, 0x06, (byte) 0x99}); // when - SensorDataCyclingCadenceAndDistanceSpeed sensor = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel("address", "sensorName", characteristic); + Pair sensor = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel("address", "sensorName", characteristic); // then - assertNull(sensor.getDistanceSpeed()); - assertEquals(200, sensor.getCadence().getCrankRevolutionsCount()); + assertNull(sensor.first); + assertEquals(200, sensor.second.crankRevolutionsCount()); } @Test @@ -29,11 +28,11 @@ public class BluetoothHandlerCyclingDistanceSpeedTest { characteristic.setValue(new byte[]{0x01, (byte) 0xFF, (byte) 0xFF, 0, 1, 0x45, (byte) 0x99}); // when - SensorDataCyclingCadenceAndDistanceSpeed sensor = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel("address", "sensorName", characteristic); + Pair sensor = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel("address", "sensorName", characteristic); // then - assertEquals(65535 + 16777216, sensor.getDistanceSpeed().getWheelRevolutionsCount()); - assertNull(sensor.getCadence()); + assertEquals(65535 + 16777216, sensor.first.wheelRevolutionsCount()); + assertNull(sensor.second); } @Test @@ -42,11 +41,11 @@ public class BluetoothHandlerCyclingDistanceSpeedTest { characteristic.setValue(new byte[]{0x03, (byte) 0xC8, 0x00, 0x00, 0x01, 0x06, (byte) 0x99, (byte) 0xE1, 0x00, 0x45, (byte) 0x99}); // when - SensorDataCyclingCadenceAndDistanceSpeed sensor = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel("address", "sensorName", characteristic); + Pair sensor = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel("address", "sensorName", characteristic); // then - assertEquals(200 + 16777216, sensor.getDistanceSpeed().getWheelRevolutionsCount()); - assertEquals(225, sensor.getCadence().getCrankRevolutionsCount()); + assertEquals(200 + 16777216, sensor.first.wheelRevolutionsCount()); + assertEquals(225, sensor.second.crankRevolutionsCount()); } } \ No newline at end of file diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingPowerTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingPowerTest.java index 36272ee4a..2f4d56e14 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingPowerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingPowerTest.java @@ -6,8 +6,6 @@ import android.bluetooth.BluetoothGattCharacteristic; import org.junit.Test; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingPower; - public class BluetoothHandlerCyclingPowerTest { @Test @@ -16,10 +14,10 @@ public class BluetoothHandlerCyclingPowerTest { characteristic.setValue(new byte[]{0, 0, 40, 0}); // when - SensorDataCyclingPower.Data powerCadence = BluetoothHandlerManagerCyclingPower.parseCyclingPower("", "", characteristic); + BluetoothHandlerManagerCyclingPower.Data powerCadence = BluetoothHandlerManagerCyclingPower.parseCyclingPower(characteristic); // then - assertEquals(40, powerCadence.power().getValue().getW(), 0.01); + assertEquals(40, powerCadence.power().getW(), 0.01); } @Test @@ -28,13 +26,13 @@ public class BluetoothHandlerCyclingPowerTest { characteristic.setValue(new byte[]{0x2C, 0x00, 0x00, 0x00, (byte) 0x9F, 0x00, 0x0C, 0x00, (byte) 0xE5, 0x42}); // when - SensorDataCyclingPower.Data powerCadence = BluetoothHandlerManagerCyclingPower.parseCyclingPower("", "", characteristic); + BluetoothHandlerManagerCyclingPower.Data powerCadence = BluetoothHandlerManagerCyclingPower.parseCyclingPower(characteristic); // then - assertEquals(0, powerCadence.power().getValue().getW(), 0.01); + assertEquals(0, powerCadence.power().getW(), 0.01); - assertEquals(12, powerCadence.cadence().getCrankRevolutionsCount()); - assertEquals(17125, powerCadence.cadence().getCrankRevolutionsTime()); + assertEquals(12, powerCadence.crank().crankRevolutionsCount()); + assertEquals(17125, powerCadence.crank().crankRevolutionsTime()); } } \ No newline at end of file diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadenceTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadenceTest.java index 053937a51..7ca2507e3 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadenceTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadenceTest.java @@ -9,7 +9,6 @@ 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.SensorDataRunning; public class BluetoothHandlerRunningSpeedAndCadenceTest { @@ -19,11 +18,11 @@ public class BluetoothHandlerRunningSpeedAndCadenceTest { characteristic.setValue(new byte[]{2, 0, 5, 80, (byte) 0xFF, (byte) 0xFF, 0, 1}); // when - SensorDataRunning sensor = BluetoothHandlerRunningSpeedAndCadence.parseRunningSpeedAndCadence("address", "sensorName", characteristic); + BluetoothHandlerRunningSpeedAndCadence.Data sensor = BluetoothHandlerRunningSpeedAndCadence.parseRunningSpeedAndCadence("sensorName", characteristic); // then - assertEquals(Speed.of(5), sensor.getSpeed()); - assertEquals(Cadence.of(80), sensor.getCadence()); - assertEquals(Distance.of(6553.5 + 1677721.6), sensor.getTotalDistance()); + assertEquals(Speed.of(5), sensor.speed()); + assertEquals(Cadence.of(80), sensor.cadence()); + assertEquals(Distance.of(6553.5 + 1677721.6), sensor.totalDistance()); } } \ 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 4dd5ca5ba..babf235f8 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java @@ -2,17 +2,17 @@ package de.dennisguse.opentracks.sensors.sensorData; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import androidx.test.ext.junit.runners.AndroidJUnit4; -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.BluetoothHandlerCyclingCadence; +import de.dennisguse.opentracks.sensors.BluetoothHandlerCyclingDistanceSpeed; import de.dennisguse.opentracks.sensors.UintUtils; @RunWith(AndroidJUnit4.class) @@ -20,12 +20,11 @@ public class SensorDataCyclingTest { @Test public void compute_cadence_1() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", 1, 1024); // 1s - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 2, 2048); // 2s + SensorDataCyclingCadence current = new SensorDataCyclingCadence("", ""); // when - current.compute(previous); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 2048))); // then assertEquals(60, current.getValue().getRPM(), 0.01); @@ -33,12 +32,11 @@ public class SensorDataCyclingTest { @Test public void compute_cadence_2() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", 1, 6184); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 2, 8016); + SensorDataCyclingCadence current = new SensorDataCyclingCadence("", ""); // when - current.compute(previous); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 6184))); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 8016))); // then assertEquals(33.53, current.getValue().getRPM(), 0.01); @@ -46,12 +44,11 @@ public class SensorDataCyclingTest { @Test public void compute_cadence_sameCount() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", 1, 1024); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 1, 2048); + SensorDataCyclingCadence current = new SensorDataCyclingCadence("", ""); // when - current.compute(previous); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 2048))); // then assertEquals(Cadence.of(0), current.getValue()); @@ -60,126 +57,72 @@ public class SensorDataCyclingTest { @Test public void compute_cadence_sameTime() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", 1, 1024); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 2, 1024); + SensorDataCyclingCadence current = new SensorDataCyclingCadence("", ""); // when - current.compute(previous); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 1024))); // then - assertFalse(current.hasValue()); + assertFalse(current.hasValue()); //TODO Cadence should be 0? } @Test public void compute_cadence_rollOverTime() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", 1, UintUtils.UINT16_MAX - 1024); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 2, 0); + SensorDataCyclingCadence current = new SensorDataCyclingCadence("", ""); // when - current.compute(previous); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, UintUtils.UINT16_MAX - 1024))); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 0))); // then assertEquals(60, current.getValue().getRPM(), 0.01); } - @Ignore("Disabled from #953") @Test @Deprecated public void compute_cadence_rollOverCount() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 0, 2048); + SensorDataCyclingCadence current = new SensorDataCyclingCadence("", ""); // when - current.compute(previous); - - // then - assertEquals(60, current.getValue().getRPM(), 0.01); - } - - @Test - public void compute_cadence_overflow() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 0, 2048); - - // when - current.compute(previous); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(UintUtils.UINT32_MAX - 1, 1024))); + current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(0, 2048))); // then + // TODO See #953 +// assertEquals(60, current.getValue().getRPM(), 0.01); assertNull(current.getValue()); } @Test public void compute_speed() { - // given - SensorDataCyclingDistanceSpeed previous = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", 1, 6184); - SensorDataCyclingDistanceSpeed current = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", 2, 8016); + SensorDataCyclingDistanceSpeed current = new SensorDataCyclingDistanceSpeed("", ""); + current.setWheelCircumference(Distance.ofMM(2150)); // when - current.compute(previous, Distance.ofMM(2150)); + current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(1, 6184))); + current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(2, 8016))); // then assertEquals(2.15, current.getValue().getDistance().toM(), 0.01); assertEquals(1.20, current.getValue().getSpeed().toMPS(), 0.01); } - @Ignore("Disabled from #953") @Test @Deprecated public void compute_speed_rollOverCount() { - // given - SensorDataCyclingDistanceSpeed previous = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); - SensorDataCyclingDistanceSpeed current = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", 0, 2048); + SensorDataCyclingDistanceSpeed current = new SensorDataCyclingDistanceSpeed("", ""); + current.setWheelCircumference(Distance.ofMM(2000)); // when - current.compute(previous, Distance.ofMM(2000)); - - // then - assertEquals(2, current.getValue().getDistance().toM(), 0.01); - assertEquals(2, current.getValue().getSpeed().toMPS(), 0.01); - } - - @Test - public void compute_speed_overflow() { - // given - SensorDataCyclingDistanceSpeed previous = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", UintUtils.UINT32_MAX - 1, 1024); - SensorDataCyclingDistanceSpeed current = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", 0, 2048); - - // when - current.compute(previous, Distance.ofMM(2000)); + current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(UintUtils.UINT32_MAX - 1, 1024))); + current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(0, 2048))); + // then + // TODO See #953 +// assertEquals(2, current.getValue().getDistance().toM(), 0.01); +// assertEquals(2, current.getValue().getSpeed().toMPS(), 0.01); assertNull(current.getValue()); } - - @Test - public void equals_speed_with_no_data() { - // given - SensorDataCyclingDistanceSpeed previous = new SensorDataCyclingDistanceSpeed("sensorAddress"); - SensorDataCyclingDistanceSpeed current = new SensorDataCyclingDistanceSpeed("sensorAddress", "sensorName", 0, 2048); - - // when - previous.toString(); - - // then - assertNotEquals(previous, current); - assertNotEquals(previous, previous); - } - - @Test - public void equals_cadence_with_no_data() { - // given - SensorDataCyclingCadence previous = new SensorDataCyclingCadence("sensorAddress"); - SensorDataCyclingCadence current = new SensorDataCyclingCadence("sensorAddress", "sensorName", 0, 2048); - - // when - previous.toString(); - - // then - assertNotEquals(previous, current); - assertNotEquals(previous, previous); - } } \ No newline at end of file diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index de9c486eb..9d7a50106 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -35,7 +35,9 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.io.file.importer.TrackPointAssert; import de.dennisguse.opentracks.sensors.AltitudeSumManager; +import de.dennisguse.opentracks.sensors.BluetoothHandlerRunningSpeedAndCadence; import de.dennisguse.opentracks.sensors.SensorManager; +import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataHeartRate; import de.dennisguse.opentracks.sensors.sensorData.SensorDataRunning; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; @@ -253,16 +255,16 @@ public class TrackRecordingServiceRecordingTest { Track.Id trackId = service.startNewTrack(); trackPointCreator.getSensorManager().setAltitudeSumManager(altitudeSumManager); SensorManager sensorManager = trackPointCreator.getSensorManager(); - + sensorManager.sensorDataSet.add(new SensorDataHeartRate("", "")); // when String sensor1 = "2020-02-02T02:02:03Z"; trackPointCreator.setClock(sensor1); - sensorManager.onChanged(new SensorDataHeartRate("", "", HeartRate.of(5))); //Should be ignored + sensorManager.onChanged(new Raw<>(HeartRate.of(5))); //Should be ignored String sensor3 = "2020-02-02T02:02:13Z"; trackPointCreator.setClock(sensor3); - sensorManager.onChanged(new SensorDataHeartRate("", "", HeartRate.of(7))); + sensorManager.onChanged(new Raw<>(HeartRate.of(7))); String stopTime = "2020-02-02T02:02:15Z"; trackPointCreator.setClock(stopTime); @@ -590,16 +592,17 @@ public class TrackRecordingServiceRecordingTest { Track.Id trackId = service.startNewTrack(); trackPointCreator.getSensorManager().setAltitudeSumManager(altitudeSumManager); SensorManager sensorManager = trackPointCreator.getSensorManager(); + sensorManager.sensorDataSet.add(new SensorDataRunning("", "")); // when String sensor1 = "2020-02-02T02:02:03Z"; trackPointCreator.setClock(sensor1); - sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(0))); //Should be ignored + sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(0)))); //Should be ignored // when String sensor2 = "2020-02-02T02:02:04Z"; trackPointCreator.setClock(sensor2); - sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(2))); + sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(2)))); // when String gps1 = "2020-02-02T02:02:05Z"; @@ -608,12 +611,12 @@ public class TrackRecordingServiceRecordingTest { // when String sensor3 = "2020-02-02T02:02:06Z"; trackPointCreator.setClock(sensor3); - sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(12))); + sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(12)))); // when String sensor4 = "2020-02-02T02:02:07Z"; trackPointCreator.setClock(sensor4); - sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(14))); //Should be ignored + sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(14)))); //Should be ignored // when String gps2 = "2020-02-02T02:02:08Z"; @@ -622,7 +625,7 @@ public class TrackRecordingServiceRecordingTest { // when String sensor5 = "2020-02-02T02:02:10Z"; trackPointCreator.setClock(sensor5); - sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(16))); //Should be ignored + sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(16)))); //Should be ignored // when String gps3 = "2020-02-02T02:02:12Z"; diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java index dd2640b72..bbb483d15 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothConnectionManager.java @@ -33,7 +33,6 @@ import androidx.annotation.NonNull; import java.util.Optional; import java.util.UUID; -import de.dennisguse.opentracks.sensors.sensorData.SensorData; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; /** @@ -140,8 +139,7 @@ public class BluetoothConnectionManager { bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, handler); - SensorData sensorData = sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress()); - observer.onChange(sensorData); + observer.onConnect(sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress())); } private synchronized void clearData() { diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java index e0f3cd320..0ba7811bc 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java @@ -22,7 +22,7 @@ public class BluetoothHandlerBarometricPressure implements SensorHandlerInterfac } @Override - public SensorData createEmptySensorData(String address) { + public SensorData createEmptySensorData(String address) { return null; //TODO } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java index 6559a6dde..c0757e1ac 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java @@ -2,12 +2,12 @@ package de.dennisguse.opentracks.sensors; import android.bluetooth.BluetoothGattCharacteristic; import android.util.Log; +import android.util.Pair; import java.util.List; +import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadence; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadenceAndDistanceSpeed; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingPower; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; public class BluetoothHandlerCyclingCadence implements SensorHandlerInterface { @@ -30,24 +30,28 @@ public class BluetoothHandlerCyclingCadence implements SensorHandlerInterface { @Override public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { - - //TODO Implement to ServiceMeasurement.parse()? if (serviceMeasurementUUID.equals(BluetoothHandlerManagerCyclingPower.CYCLING_POWER)) { - SensorDataCyclingPower.Data data = BluetoothHandlerManagerCyclingPower.parseCyclingPower(address, sensorName, characteristic); - if (data!= null) { - observer.onChange(data.cadence()); - } - } else if (serviceMeasurementUUID.equals(BluetoothHandlerCyclingDistanceSpeed.CYCLING_SPEED_CADENCE)) { - SensorDataCyclingCadenceAndDistanceSpeed cadenceAndSpeed = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel(address, sensorName, characteristic); - if (cadenceAndSpeed == null) { - return; + BluetoothHandlerManagerCyclingPower.Data data = BluetoothHandlerManagerCyclingPower.parseCyclingPower(characteristic); + if (data != null && data.crank() != null) { + observer.onChange(new Raw<>(data.crank())); } + return; + } - if (cadenceAndSpeed.getCadence() != null) { - observer.onChange(cadenceAndSpeed.getCadence()); + if (serviceMeasurementUUID.equals(BluetoothHandlerCyclingDistanceSpeed.CYCLING_SPEED_CADENCE)) { + Pair data = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel(address, sensorName, characteristic); + + if (data != null && data.second != null) { + observer.onChange(new Raw<>(data.second)); } + return; } Log.e(TAG, "Don't know how to decode this payload."); } + + public record CrankData( + long crankRevolutionsCount, // UINT32 + int crankRevolutionsTime // UINT16; 1/1024s + ) {} } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java index d13c7f8de..f9c64a1e1 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java @@ -1,6 +1,7 @@ package de.dennisguse.opentracks.sensors; import android.bluetooth.BluetoothGattCharacteristic; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; @@ -8,8 +9,7 @@ import androidx.annotation.VisibleForTesting; import java.util.List; import java.util.UUID; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadence; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadenceAndDistanceSpeed; +import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingDistanceSpeed; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; @@ -32,19 +32,15 @@ public class BluetoothHandlerCyclingDistanceSpeed implements SensorHandlerInterf @Override public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { - SensorDataCyclingCadenceAndDistanceSpeed cadenceAndSpeed = parseCyclingCrankAndWheel(address, sensorName, characteristic); - if (cadenceAndSpeed == null) { - return; - } - - if (cadenceAndSpeed.getDistanceSpeed() != null) { - observer.onChange(cadenceAndSpeed.getDistanceSpeed()); + Pair data = parseCyclingCrankAndWheel(address, sensorName, characteristic); + if (data.first != null) { + observer.onChange(new Raw<>(data.first)); } } @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) - public static SensorDataCyclingCadenceAndDistanceSpeed parseCyclingCrankAndWheel(String address, String sensorName, @NonNull BluetoothGattCharacteristic characteristic) { + public static Pair parseCyclingCrankAndWheel(String address, String sensorName, @NonNull BluetoothGattCharacteristic characteristic) { // DOCUMENTATION https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.csc_measurement.xml int valueLength = characteristic.getValue().length; if (valueLength == 0) { @@ -56,24 +52,31 @@ public class BluetoothHandlerCyclingDistanceSpeed implements SensorHandlerInterf boolean hasCrank = (flags & 0x02) > 0; int index = 1; - SensorDataCyclingDistanceSpeed speed = null; + WheelData wheelData = null; if (hasWheel && valueLength - index >= 6) { - int wheelTotalRevolutionCount = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, index); + long wheelTotalRevolutionCount = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, index); index += 4; int wheelTime = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, index); // 1/1024s - speed = new SensorDataCyclingDistanceSpeed(address, sensorName, wheelTotalRevolutionCount, wheelTime); + wheelData = new WheelData(wheelTotalRevolutionCount, wheelTime); index += 2; } - SensorDataCyclingCadence cadence = null; + BluetoothHandlerCyclingCadence.CrankData crankData = 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 SensorDataCyclingCadence(address, sensorName, crankCount, crankTime); + crankData = new BluetoothHandlerCyclingCadence.CrankData(crankCount, crankTime); } - return new SensorDataCyclingCadenceAndDistanceSpeed(address, sensorName, cadence, speed); + return new Pair<>(wheelData, crankData); } + + public record WheelData( + + long wheelRevolutionsCount, // UINT32 + + int wheelRevolutionsTime // UINT16; 1/1024s + ) {} } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java index ec65ebc7c..1605dec08 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java @@ -9,7 +9,7 @@ import java.util.List; import java.util.UUID; import de.dennisguse.opentracks.data.models.Power; -import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadence; +import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingPower; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; @@ -32,16 +32,16 @@ public class BluetoothHandlerManagerCyclingPower implements SensorHandlerInterfa @Override public void handlePayload(SensorManager.SensorDataChangedObserver observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { - SensorDataCyclingPower.Data cyclingPower = parseCyclingPower(address, sensorName, characteristic); + Data cyclingPower = parseCyclingPower(characteristic); if (cyclingPower != null) { - observer.onChange(cyclingPower.power()); + observer.onChange(new Raw<>(cyclingPower)); } } - @VisibleForTesting - public static SensorDataCyclingPower.Data parseCyclingPower(String address, String sensorName, BluetoothGattCharacteristic characteristic) { + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public static Data parseCyclingPower(BluetoothGattCharacteristic characteristic) { // DOCUMENTATION https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.cycling_power_measurement.xml int valueLength = characteristic.getValue().length; if (valueLength == 0) { @@ -69,18 +69,19 @@ public class BluetoothHandlerManagerCyclingPower implements SensorHandlerInterfa index += 2 + 2; } - SensorDataCyclingCadence cadence = null; + BluetoothHandlerCyclingCadence.CrankData crankData = 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 SensorDataCyclingCadence(address, sensorName, crankCount, crankTime); + crankData = new BluetoothHandlerCyclingCadence.CrankData(crankCount, crankTime); } - - return new SensorDataCyclingPower.Data(new SensorDataCyclingPower(sensorName, address, Power.of(instantaneousPower)), cadence); + return new Data(Power.of(instantaneousPower), crankData); } + public record Data(Power power, BluetoothHandlerCyclingCadence.CrankData crank) {} + } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java index 7b32af948..1af0d581f 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.UUID; import de.dennisguse.opentracks.data.models.HeartRate; +import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataHeartRate; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; @@ -44,7 +45,7 @@ public class BluetoothHandlerManagerHeartRate implements SensorHandlerInterface HeartRate heartRate = parseHeartRate(characteristic); if (heartRate != null) { - observer.onChange(new SensorDataHeartRate(address, sensorName, heartRate)); + observer.onChange(new Raw<>(heartRate)); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java index 6add68d39..ffc293ca5 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java @@ -11,6 +11,7 @@ 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.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataRunning; import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface; @@ -34,11 +35,12 @@ public class BluetoothHandlerRunningSpeedAndCadence implements SensorHandlerInte @Override public void handlePayload(SensorManager.SensorDataChangedObserver observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { - observer.onChange(parseRunningSpeedAndCadence(address, sensorName, characteristic)); + Data data = parseRunningSpeedAndCadence(sensorName, characteristic); + observer.onChange(new Raw<>(data)); } @VisibleForTesting - public static SensorDataRunning parseRunningSpeedAndCadence(String address, String sensorName, @NonNull BluetoothGattCharacteristic characteristic) { + public static Data parseRunningSpeedAndCadence(String sensorName, @NonNull BluetoothGattCharacteristic characteristic) { // DOCUMENTATION https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.rsc_measurement.xml int valueLength = characteristic.getValue().length; if (valueLength == 0) { @@ -79,6 +81,8 @@ public class BluetoothHandlerRunningSpeedAndCadence implements SensorHandlerInte totalDistance = Distance.ofDM(characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, index)); } - return new SensorDataRunning(address, sensorName, speed, cadence, totalDistance); + return new Data(speed, cadence, totalDistance); } + + public record Data(Speed speed, Cadence cadence, Distance totalDistance) {} } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java index d9258738d..96f62779b 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java @@ -50,7 +50,7 @@ public class BluetoothRemoteSensorManager implements SensorConnector, SharedPref private static final String TAG = BluetoothRemoteSensorManager.class.getSimpleName(); - public static final Duration MAX_SENSOR_DATE_SET_AGE = Duration.ofSeconds(5); + public static final Duration MAX_SENSOR_DATE_SET_AGE = Duration.ofSeconds(50); //TODO private final BluetoothAdapter bluetoothAdapter; private final Context context; diff --git a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java index cc79da9bb..6fd6a768f 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java @@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import de.dennisguse.opentracks.data.models.TrackPoint; +import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorData; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.handlers.GPSManager; @@ -27,13 +28,19 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange private final SensorDataChangedObserver listener = new SensorDataChangedObserver() { @Override - public void onChange(SensorData sensorData) { - sensorDataSet.set(sensorData); + public void onConnect(SensorData sensorData) { + sensorDataSet.add(sensorData); observer.onChange(new SensorDataSet(sensorDataSet)); } @Override - public void onDisconnect(SensorData sensorData) { + public void onChange(Raw sensorData) { + sensorDataSet.update(sensorData); + observer.onChange(new SensorDataSet(sensorDataSet)); + } + + @Override + public void onDisconnect(SensorData sensorData) { sensorDataSet.remove(sensorData); observer.onChange(new SensorDataSet(sensorDataSet)); } @@ -91,7 +98,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange @Deprecated @VisibleForTesting - public void onChanged(SensorData data) { + public void onChanged(Raw data) { listener.onChange(data); } @@ -120,8 +127,10 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange } public interface SensorDataChangedObserver { - void onChange(SensorData sensorData); - void onDisconnect(SensorData sensorData); + void onConnect(SensorData sensorData); + void onChange(Raw sensorData); + + void onDisconnect(SensorData sensorData); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java new file mode 100644 index 000000000..5f88bb229 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java @@ -0,0 +1,16 @@ +package de.dennisguse.opentracks.sensors.sensorData; + + +import androidx.annotation.NonNull; + +import java.time.Instant; + +public record Raw( + @NonNull T value, + + @NonNull Instant time +) { + public Raw(@NonNull T value) { + this(value, Instant.now()); //TODO We should be using the MonotonicClock + } +} 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 365d6bc48..aa59c24d7 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorData.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorData.java @@ -1,48 +1,48 @@ package de.dennisguse.opentracks.sensors.sensorData; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import java.time.Instant; import de.dennisguse.opentracks.sensors.BluetoothRemoteSensorManager; -public abstract class SensorData { +public abstract class SensorData { - protected T value; + protected Raw previous; + + protected Output value; private final String sensorAddress; private final String sensorName; - private final Instant time; - SensorData(String sensorAddress) { this(sensorAddress, null); } SensorData(String sensorAddress, String sensorName) { - this(sensorAddress, sensorName, Instant.now()); - } - - @VisibleForTesting - SensorData(String sensorAddress, String sensorName, Instant time) { this.sensorAddress = sensorAddress; this.sensorName = sensorName; - this.time = time; } public String getSensorNameOrAddress() { return sensorName != null ? sensorName : sensorAddress; } + public final void add(Raw current) { + computeValue(current); + previous = current; + } + + protected abstract void computeValue(Raw current); + public boolean hasValue() { return value != null; } @NonNull - protected abstract T getNoneValue(); + protected abstract Output getNoneValue(); - public T getValue() { + public Output getValue() { if (!hasValue()) { return null; } @@ -55,20 +55,23 @@ public abstract class SensorData { /** * Reset long term aggregated values (more than derived from previous SensorData). e.g. overall distance. */ - public void reset() { - } + public void reset() {}; /** * Is the data recent considering the current time. */ private boolean isRecent() { + if (previous == null) { + return false; + } + return Instant.now() - .isBefore(time.plus(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE)); + .isBefore(previous.time().plus(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE)); } @NonNull @Override public String toString() { - return "sensorAddress='" + sensorAddress; + return "sensorAddress=" + sensorAddress + " data=" + value; } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadence.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadence.java index 0fbdb193e..a1ab8c4ba 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadence.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadence.java @@ -3,53 +3,29 @@ package de.dennisguse.opentracks.sensors.sensorData; import android.util.Log; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import java.time.Duration; import de.dennisguse.opentracks.data.models.Cadence; +import de.dennisguse.opentracks.sensors.BluetoothHandlerCyclingCadence; import de.dennisguse.opentracks.sensors.UintUtils; -public class SensorDataCyclingCadence extends SensorData { +public class SensorDataCyclingCadence extends SensorData { private final String TAG = SensorDataCyclingCadence.class.getSimpleName(); - private final Long crankRevolutionsCount; // UINT32 - private final Integer crankRevolutionsTime; // UINT16; 1/1024s - public SensorDataCyclingCadence(String sensorAddress) { super(sensorAddress); - this.crankRevolutionsCount = null; - this.crankRevolutionsTime = null; } - public SensorDataCyclingCadence(String sensorAddress, String sensorName, long crankRevolutionsCount, int crankRevolutionsTime) { + public SensorDataCyclingCadence(String sensorAddress, String sensorName) { super(sensorAddress, sensorName); - this.crankRevolutionsCount = crankRevolutionsCount; - this.crankRevolutionsTime = crankRevolutionsTime; } - public boolean hasData() { - return crankRevolutionsCount != null && crankRevolutionsTime != null; - } - - public long getCrankRevolutionsCount() { - return crankRevolutionsCount; - } - - public int getCrankRevolutionsTime() { - return crankRevolutionsTime; - } - - @NonNull @Override - protected Cadence getNoneValue() { - return Cadence.of(0); - } - - public void compute(SensorDataCyclingCadence previous) { - if (hasData() && previous != null && previous.hasData()) { - float timeDiff_ms = UintUtils.diff(crankRevolutionsTime, previous.crankRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * 1000; + protected void computeValue(Raw current) { + if (previous != null) { + float timeDiff_ms = UintUtils.diff(current.value().crankRevolutionsTime(), previous.value().crankRevolutionsTime(), UintUtils.UINT16_MAX) / 1024f * 1000; Duration timeDiff = Duration.ofMillis((long) timeDiff_ms); if (timeDiff.isZero() || timeDiff.isNegative()) { Log.e(TAG, "Timestamps difference is invalid: cannot compute cadence."); @@ -58,30 +34,19 @@ public class SensorDataCyclingCadence extends SensorData { } // TODO We have to treat with overflow according to the documentation: read https://github.com/OpenTracksApp/OpenTracks/pull/953#discussion_r711625268 - if (crankRevolutionsCount < previous.crankRevolutionsCount) { + if (current.value().crankRevolutionsCount() < previous.value().crankRevolutionsCount()) { Log.e(TAG, "Crank revolutions count difference is invalid: cannot compute cadence."); return; } - long crankDiff = UintUtils.diff(crankRevolutionsCount, previous.crankRevolutionsCount, UintUtils.UINT32_MAX); + long crankDiff = UintUtils.diff(current.value().crankRevolutionsCount(), previous.value().crankRevolutionsCount(), UintUtils.UINT32_MAX); value = Cadence.of(crankDiff, timeDiff); } } @NonNull @Override - public String toString() { - return super.toString() + " cadence=" + value + " time=" + crankRevolutionsTime + " count=" + crankRevolutionsCount; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (!(obj instanceof SensorDataCyclingCadence comp)) return false; - - if (hasData() && comp.hasData() == hasData()) { - return getCrankRevolutionsCount() == comp.getCrankRevolutionsCount() && getCrankRevolutionsTime() == comp.getCrankRevolutionsTime(); - } else { - return false; - } + protected Cadence getNoneValue() { + return Cadence.of(0); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadenceAndDistanceSpeed.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadenceAndDistanceSpeed.java deleted file mode 100644 index 26d4cd9c2..000000000 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingCadenceAndDistanceSpeed.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.dennisguse.opentracks.sensors.sensorData; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.util.Pair; - -public class SensorDataCyclingCadenceAndDistanceSpeed extends SensorData> { - - public SensorDataCyclingCadenceAndDistanceSpeed(String sensorAddress, String sensorName, @Nullable SensorDataCyclingCadence cadence, @Nullable SensorDataCyclingDistanceSpeed distanceSpeed) { - super(sensorAddress, sensorName); - this.value = new Pair<>(cadence, distanceSpeed); - } - - public SensorDataCyclingCadence getCadence() { - return this.value != null ? this.value.first : null; - } - - public SensorDataCyclingDistanceSpeed getDistanceSpeed() { - return this.value != null ? this.value.second : null; - } - - @NonNull - @Override - protected Pair getNoneValue() { - return new Pair<>(null, null); - } -} diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingDistanceSpeed.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingDistanceSpeed.java index 0e76713ac..7f9641a1e 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingDistanceSpeed.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingDistanceSpeed.java @@ -3,58 +3,32 @@ package de.dennisguse.opentracks.sensors.sensorData; import android.util.Log; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import java.time.Duration; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.sensors.BluetoothHandlerCyclingDistanceSpeed; import de.dennisguse.opentracks.sensors.UintUtils; -public class SensorDataCyclingDistanceSpeed extends SensorData { +public class SensorDataCyclingDistanceSpeed extends SensorData { private final String TAG = SensorDataCyclingDistanceSpeed.class.getSimpleName(); - private final Long wheelRevolutionsCount; // UINT32 - private final Integer wheelRevolutionsTime; // UINT16; 1/1024s + private Distance wheelCircumference; public SensorDataCyclingDistanceSpeed(String sensorAddress) { super(sensorAddress); - this.wheelRevolutionsCount = null; - this.wheelRevolutionsTime = null; } - public SensorDataCyclingDistanceSpeed(String sensorAddress, String sensorName, long wheelRevolutionsCount, int wheelRevolutionsTime) { + public SensorDataCyclingDistanceSpeed(String sensorAddress, String sensorName) { super(sensorAddress, sensorName); - this.wheelRevolutionsCount = wheelRevolutionsCount; - this.wheelRevolutionsTime = wheelRevolutionsTime; } - public boolean hasData() { - return wheelRevolutionsCount != null && wheelRevolutionsTime != null; - } - - public long getWheelRevolutionsCount() { - return wheelRevolutionsCount; - } - - public int getWheelRevolutionsTime() { - return wheelRevolutionsTime; - } - - @NonNull @Override - protected Data getNoneValue() { - if (value != null) { - return new Data(value.distance, value.distanceOverall, Speed.zero()); - } else { - return new Data(Distance.of(0), Distance.of(0), Speed.zero()); - } - } - - public void compute(SensorDataCyclingDistanceSpeed previous, Distance wheelCircumference) { - if (hasData() && previous != null && previous.hasData()) { - float timeDiff_ms = UintUtils.diff(wheelRevolutionsTime, previous.wheelRevolutionsTime, UintUtils.UINT16_MAX) / 1024f * 1000; + protected void computeValue(Raw current) { + if (previous != null) { + float timeDiff_ms = UintUtils.diff(current.value().wheelRevolutionsTime(), previous.value().wheelRevolutionsTime(), UintUtils.UINT16_MAX) / 1024f * 1000; Duration timeDiff = Duration.ofMillis((long) timeDiff_ms); if (timeDiff.isZero() || timeDiff.isNegative()) { Log.e(TAG, "Timestamps difference is invalid: cannot compute speed."); @@ -62,16 +36,16 @@ public class SensorDataCyclingDistanceSpeed extends SensorData type, @Nullable SensorData sensorData) { - if (type instanceof SensorDataHeartRate) { - this.heartRate = (SensorDataHeartRate) sensorData; + private void set(@NonNull SensorData type, @Nullable SensorData sensorData) { + if (type instanceof SensorDataHeartRate hr) { + heartRate = hr; return; } - - if (type instanceof SensorDataCyclingCadence) { - SensorDataCyclingCadence previous = getCyclingCadence(); - Log.d(TAG, "Previous: " + previous + "; current: " + sensorData); - - if (sensorData != null && sensorData.equals(previous)) { - Log.d(TAG, "onChanged: cadence data repeated."); - return; - } - - this.cyclingCadence = (SensorDataCyclingCadence) sensorData; - if (this.cyclingCadence != null) { - this.cyclingCadence.compute(previous); - } + if (type instanceof SensorDataCyclingCadence cc) { + cyclingCadence = cc; return; } - - if (type instanceof SensorDataCyclingDistanceSpeed) { - SensorDataCyclingDistanceSpeed previous = getCyclingDistanceSpeed(); - Log.d(TAG, "Previous: " + previous + "; Current" + sensorData); - if (sensorData != null && sensorData.equals(previous)) { - Log.d(TAG, "onChanged: cycling speed data repeated."); - return; - } - Distance preferenceWheelCircumference = PreferencesUtils.getWheelCircumference(); //TODO Fetch once and then listen for changes. - - this.cyclingDistanceSpeed = (SensorDataCyclingDistanceSpeed) sensorData; - if (this.cyclingDistanceSpeed != null) { - this.cyclingDistanceSpeed.compute(previous, preferenceWheelCircumference); - } + if (type instanceof SensorDataCyclingDistanceSpeed ds) { + cyclingDistanceSpeed = ds; return; } - - if (type instanceof SensorDataCyclingPower) { - this.cyclingPower = (SensorDataCyclingPower) sensorData; + if (type instanceof SensorDataCyclingPower cp) { + cyclingPower = cp; return; } - - if (type instanceof SensorDataRunning) { - SensorDataRunning previous = getRunningDistanceSpeedCadence(); - Log.d(TAG, "Previous: " + previous + "; Current" + sensorData); - if (sensorData != null && sensorData.equals(previous)) { - Log.d(TAG, "onChanged: running speed data repeated."); - return; - } - - this.runningDistanceSpeedCadence = (SensorDataRunning) sensorData; - if (this.runningDistanceSpeedCadence != null) { - this.runningDistanceSpeedCadence.compute(previous); - } + if (type instanceof SensorDataRunning rr) { + runningDistanceSpeedCadence = rr; return; } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorHandlerInterface.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorHandlerInterface.java index 215b86dab..9893ae556 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorHandlerInterface.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorHandlerInterface.java @@ -11,7 +11,7 @@ public interface SensorHandlerInterface { List getServices(); - SensorData createEmptySensorData(String address); + SensorData createEmptySensorData(String address); void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic); }