Sensor: adding Running Speed and Cadence.

Fixes #891.
This commit is contained in:
Dennis Guse
2021-07-21 22:26:57 +02:00
parent eba7a7fd89
commit 242147e491
16 changed files with 295 additions and 17 deletions
@@ -34,13 +34,14 @@ import de.dennisguse.opentracks.content.sensor.SensorData;
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
import de.dennisguse.opentracks.content.sensor.SensorDataCyclingPower;
import de.dennisguse.opentracks.content.sensor.SensorDataHeartRate;
import de.dennisguse.opentracks.content.sensor.SensorDataRunning;
import de.dennisguse.opentracks.util.BluetoothUtils;
/**
* Manages connection to a Bluetooth LE sensor and subscribes for onChange-notifications.
* Also parses the transferred data into {@link SensorDataObserver}.
*/
public abstract class BluetoothConnectionManager {
public abstract class BluetoothConnectionManager<DataType> {
private static final String TAG = BluetoothConnectionManager.class.getSimpleName();
@@ -103,7 +104,7 @@ public abstract class BluetoothConnectionManager {
public void onCharacteristicChanged(BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic) {
Log.d(TAG, "Received data from " + gatt.getDevice().getAddress());
SensorData<?> sensorData = parsePayload(gatt.getDevice().getName(), gatt.getDevice().getAddress(), characteristic);
SensorData<DataType> sensorData = parsePayload(gatt.getDevice().getName(), gatt.getDevice().getAddress(), characteristic);
if (sensorData != null) {
Log.d(TAG, "Decoded data from " + gatt.getDevice().getAddress() + ": " + sensorData);
observer.onChanged(sensorData);
@@ -148,14 +149,14 @@ public abstract class BluetoothConnectionManager {
return address.equals(bluetoothGatt.getDevice().getAddress());
}
protected abstract SensorData<?> createEmptySensorData(String address);
protected abstract SensorData<DataType> createEmptySensorData(String address);
/**
* @return null if data could not be parsed.
*/
protected abstract SensorData<?> parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic);
protected abstract SensorData<DataType> parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic);
public static class HeartRate extends BluetoothConnectionManager {
public static class HeartRate extends BluetoothConnectionManager<Float> {
HeartRate(@NonNull SensorDataObserver observer) {
super(BluetoothUtils.HEART_RATE_SERVICE_UUID, BluetoothUtils.HEART_RATE_MEASUREMENT_CHAR_UUID, observer);
@@ -174,7 +175,7 @@ public abstract class BluetoothConnectionManager {
}
}
public static class CyclingCadence extends BluetoothConnectionManager {
public static class CyclingCadence extends BluetoothConnectionManager<Float> {
CyclingCadence(SensorDataObserver observer) {
super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
@@ -205,7 +206,7 @@ public abstract class BluetoothConnectionManager {
}
}
public static class CyclingDistanceSpeed extends BluetoothConnectionManager {
public static class CyclingDistanceSpeed extends BluetoothConnectionManager<SensorDataCycling.DistanceSpeed.Data> {
CyclingDistanceSpeed(SensorDataObserver observer) {
super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
@@ -232,7 +233,7 @@ public abstract class BluetoothConnectionManager {
}
}
public static class CyclingPower extends BluetoothConnectionManager {
public static class CyclingPower extends BluetoothConnectionManager<Float> {
CyclingPower(@NonNull SensorDataObserver observer) {
super(BluetoothUtils.CYCLING_POWER_UUID, BluetoothUtils.CYCLING_POWER_MEASUREMENT_CHAR_UUID, observer);
@@ -251,6 +252,23 @@ public abstract class BluetoothConnectionManager {
}
}
public static class RunningSpeedAndCadence extends BluetoothConnectionManager<SensorDataRunning.Data> {
RunningSpeedAndCadence(@NonNull SensorDataObserver observer) {
super(BluetoothUtils.RUNNING_RUNNING_SPEED_CADENCE_UUID, BluetoothUtils.RUNNING_RUNNING_SPEED_CADENCE_CHAR_UUID, observer);
}
@Override
protected SensorDataRunning createEmptySensorData(String address) {
return new SensorDataRunning(address);
}
@Override
protected SensorDataRunning parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
return BluetoothUtils.parseRunningSpeedAndCadence(address, sensorName, characteristic);
}
}
interface SensorDataObserver {
void onChanged(SensorData<?> sensorData);
@@ -31,6 +31,7 @@ import de.dennisguse.opentracks.content.data.Distance;
import de.dennisguse.opentracks.content.data.TrackPoint;
import de.dennisguse.opentracks.content.sensor.SensorData;
import de.dennisguse.opentracks.content.sensor.SensorDataCycling;
import de.dennisguse.opentracks.content.sensor.SensorDataRunning;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
import de.dennisguse.opentracks.util.BluetoothUtils;
import de.dennisguse.opentracks.util.PreferencesUtils;
@@ -67,6 +68,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
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);
private final BluetoothConnectionManager.RunningSpeedAndCadence runningSpeedAndCadence = new BluetoothConnectionManager.RunningSpeedAndCadence(this);
private final SensorDataSet sensorDataSet = new SensorDataSet();
@@ -85,11 +87,14 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
connect(cyclingCadence, address);
}
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) {
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_speed_key, key)) {
String address = PreferencesUtils.getBluetoothCyclingSpeedSensorAddress(sharedPreferences, context);
connect(cyclingSpeed, address);
}
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_speed_wheel_circumference_key, key)) {
preferenceWheelCircumference = PreferencesUtils.getWheelCircumference(sharedPreferences, context);
}
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_power_key, key)) {
String address = PreferencesUtils.getBluetoothCyclingPowerSensorAddress(sharedPreferences, context);
@@ -97,8 +102,11 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
connect(cyclingPower, address);
}
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_speed_wheel_circumference_key, key)) {
preferenceWheelCircumference = PreferencesUtils.getWheelCircumference(sharedPreferences, context);
if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_running_speed_and_cadence_key, key)) {
String address = PreferencesUtils.getBluetoothRunningSpeedAndCadenceAddress(sharedPreferences, context);
connect(runningSpeedAndCadence, address);
}
}
};
@@ -122,6 +130,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
cyclingCadence.disconnect();
cyclingSpeed.disconnect();
cyclingPower.disconnect();
runningSpeedAndCadence.disconnect();
sensorDataSet.clear();
@@ -133,7 +142,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
private synchronized void connect(BluetoothConnectionManager connectionManager, String address) {
private synchronized void connect(BluetoothConnectionManager<?> connectionManager, String address) {
if (!isEnabled()) {
Log.w(TAG, "Bluetooth not enabled.");
return;
@@ -186,11 +195,20 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
SensorDataCycling.DistanceSpeed previous = sensorDataSet.getCyclingDistanceSpeed();
Log.d(TAG, "Previous: " + previous + "; Current" + sensorData);
if (sensorData.equals(previous)) {
Log.d(TAG, "onChanged: speed data repeated.");
Log.d(TAG, "onChanged: cycling speed data repeated.");
return;
}
((SensorDataCycling.DistanceSpeed) sensorData).compute(previous, preferenceWheelCircumference);
}
if (sensorData instanceof SensorDataRunning) {
SensorDataRunning previous = sensorDataSet.getRunningDistanceSpeedCadence();
Log.d(TAG, "Previous: " + previous + "; Current" + sensorData);
if (sensorData.equals(previous)) {
Log.d(TAG, "onChanged: running speed data repeated.");
return;
}
((SensorDataRunning) sensorData).compute(previous);
}
sensorDataSet.set(sensorData);
}