diff --git a/README_TESTED_SENSORS.md b/README_TESTED_SENSORS.md
index 58f8dc3d0..3e6437c08 100644
--- a/README_TESTED_SENSORS.md
+++ b/README_TESTED_SENSORS.md
@@ -26,3 +26,13 @@ However, often only one value is provided.
* Wahoo Cadence (Model: WFPODCAD2)
This sensor reports cadence data as speed.
A workaround is in place.
+
+## Cycling Power Measurement
+
+We only support _Instantaneous Power_.
+
+* QUARQ Red DZero Powermeter
+* Wahoo Kickr v4.0
+ WARNING: we only support physically movements with valid GPS coordinates.
+ Using a device indoors (no GPS available) will only show the current power values, but won't store anything.
+ Also the distance is not computed.
\ No newline at end of file
diff --git a/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java
index 30cf4dcc1..5137e9f6d 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/util/BluetoothUtilsTest.java
@@ -75,4 +75,16 @@ public class BluetoothUtilsTest {
assertEquals(200, sensor.getCadence().getCrankRevolutionsCount());
assertEquals(225, sensor.getSpeed().getWheelRevolutionsCount());
}
+
+ @Test
+ public void parseCyclingPower_power() {
+ BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(BluetoothUtils.CYCLING_POWER_MEASUREMENT_CHAR_UUID, 0, 0);
+ characteristic.setValue(new byte[]{0, 0, 40, 0});
+
+ // when
+ int power_w = BluetoothUtils.parseCyclingPower(characteristic);
+
+ // then
+ assertEquals(40, power_w);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java
new file mode 100644
index 000000000..705f58695
--- /dev/null
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataCyclingPower.java
@@ -0,0 +1,32 @@
+package de.dennisguse.opentracks.content.sensor;
+
+import androidx.annotation.NonNull;
+
+public class SensorDataCyclingPower extends SensorData {
+
+ private final Float power_w;
+
+ public SensorDataCyclingPower(String address) {
+ super(address);
+ this.power_w = null;
+ }
+
+ public SensorDataCyclingPower(String name, String address, float power_w) {
+ super(name, address);
+ this.power_w = power_w;
+ }
+
+ public boolean hasPower_w() {
+ return power_w != null;
+ }
+
+ public float getPower_w() {
+ return power_w;
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "power=" + power_w;
+ }
+}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
index 9610f970a..7d9bd402c 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
@@ -12,6 +12,8 @@ public final class SensorDataSet {
private SensorDataCycling.Speed cyclingSpeed;
+ private SensorDataCyclingPower cyclingPower;
+
public SensorDataSet() {
}
@@ -27,6 +29,10 @@ public final class SensorDataSet {
return cyclingSpeed;
}
+ public SensorDataCyclingPower getCyclingPower() {
+ return cyclingPower;
+ }
+
public void set(SensorData data) {
set(data, data);
}
@@ -39,6 +45,7 @@ public final class SensorDataSet {
this.heartRate = null;
this.cyclingCadence = null;
this.cyclingSpeed = null;
+ this.cyclingPower = null;
}
public void fillTrackPoint(TrackPoint trackPoint) {
@@ -53,6 +60,10 @@ public final class SensorDataSet {
if (cyclingSpeed != null && cyclingSpeed.hasSpeed_mps()) {
trackPoint.setSpeed(cyclingSpeed.getSpeed_mps());
}
+
+ if (cyclingPower != null && cyclingPower.hasPower_w()) {
+ trackPoint.setPower(cyclingPower.getPower_w());
+ }
}
@NonNull
@@ -60,10 +71,11 @@ public final class SensorDataSet {
public String toString() {
return (getHeartRate() != null ? "" + getHeartRate() : "")
+ (getCyclingCadence() != null ? " " + getCyclingCadence() : "")
- + (getCyclingSpeed() != null ? " " + getCyclingSpeed() : "");
+ + (getCyclingSpeed() != null ? " " + getCyclingSpeed() : "")
+ + (getCyclingPower() != null ? " " + getCyclingPower() : "");
}
- private void set(SensorData type, SensorData data) {
+ private void set(@NonNull SensorData type, SensorData data) {
if (type instanceof SensorDataHeartRate) {
this.heartRate = (SensorDataHeartRate) data;
return;
@@ -78,6 +90,11 @@ public final class SensorDataSet {
return;
}
- throw new UnsupportedOperationException();
+ if (type instanceof SensorDataCyclingPower) {
+ this.cyclingPower = (SensorDataCyclingPower) data;
+ return;
+ }
+
+ throw new UnsupportedOperationException(type.getClass().getCanonicalName());
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
index 52d236ca0..c801de5bc 100644
--- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
+++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordingFragment.java
@@ -22,6 +22,7 @@ import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.data.TrackPoint;
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.SensorDataSet;
import de.dennisguse.opentracks.databinding.StatisticsRecordingBinding;
@@ -273,9 +274,9 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
if (sensorDataSet != null) {
setHeartRateSensorData(sensorDataSet);
setCadenceSensorData(sensorDataSet);
- setSpeedSensorData(sensorDataSet, isSelectedTrackRecording());
+ setPowerSensorData(sensorDataSet);
+ setSpeedSensorData(sensorDataSet);
}
-
setTotalElevationGain(trackRecordingService.getElevationGain_m());
}
}
@@ -320,6 +321,29 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
viewBinding.statsSensorCadenceValue.setText(sensorValue);
}
+ private void setPowerSensorData(SensorDataSet sensorDataSet) {
+ int isVisible = View.VISIBLE;
+ if (PreferencesUtils.isBluetoothCyclingPowerSensorAddressNone(getContext())) {
+ isVisible = View.GONE;
+ }
+ viewBinding.statsSensorPowerGroup.setVisibility(isVisible);
+ setVisibilitySensorHorizontalLine();
+
+ String sensorValue = getContext().getString(R.string.value_unknown);
+ String sensorName = getContext().getString(R.string.value_unknown);
+ if (sensorDataSet != null && sensorDataSet.getCyclingPower() != null) {
+ SensorDataCyclingPower data = sensorDataSet.getCyclingPower();
+ sensorName = data.getSensorName();
+
+ if (data.hasPower_w() && data.isRecent()) {
+ sensorValue = StringUtils.formatDecimal(data.getPower_w(), 0);
+ }
+ }
+
+ viewBinding.statsSensorPowerSensorValue.setText(sensorName);
+ viewBinding.statsSensorPowerValue.setText(sensorValue);
+ }
+
// Set elevation gain
private void setTotalElevationGain(Float elevationGain_m) {
//TODO Check if we can distribute the total elevation gain via trackStatistics instead of doing some computation in the UI layer.
@@ -349,14 +373,12 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
}
}
- private void setSpeedSensorData(SensorDataSet sensorDataSet, boolean isRecording) {
- if (isRecording) {
- if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
- SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed();
+ private void setSpeedSensorData(SensorDataSet sensorDataSet) {
+ if (sensorDataSet != null && sensorDataSet.getCyclingSpeed() != null) {
+ SensorDataCycling.Speed data = sensorDataSet.getCyclingSpeed();
- if (data.hasSpeed_mps() && data.isRecent()) {
- setSpeed(data.getSpeed_mps());
- }
+ if (data.hasSpeed_mps() && data.isRecent()) {
+ setSpeed(data.getSpeed_mps());
}
}
}
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
index df2a92e48..671ec09ad 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
@@ -32,6 +32,7 @@ import java.util.UUID;
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.util.BluetoothUtils;
@@ -88,8 +89,14 @@ public abstract class BluetoothConnectionManager {
// Register for updates.
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(BluetoothUtils.CLIENT_CHARACTERISTIC_CONFIG_UUID);
+ if (descriptor == null) {
+ Log.e(TAG, "CLIENT_CHARACTERISTIC_CONFIG_UUID characteristic not available; cannot request notifications for changed data.");
+ return;
+ }
+
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
+
}
@Override
@@ -170,7 +177,7 @@ public abstract class BluetoothConnectionManager {
public static class CyclingCadence extends BluetoothConnectionManager {
CyclingCadence(SensorDataObserver observer) {
- super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPPED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
+ super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
}
@Override
@@ -201,7 +208,7 @@ public abstract class BluetoothConnectionManager {
public static class CyclingSpeed extends BluetoothConnectionManager {
CyclingSpeed(SensorDataObserver observer) {
- super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPPED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
+ super(BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID, BluetoothUtils.CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID, observer);
}
@Override
@@ -219,6 +226,25 @@ public abstract class BluetoothConnectionManager {
}
}
+ public static class CyclingPower extends BluetoothConnectionManager {
+
+ CyclingPower(@NonNull SensorDataObserver observer) {
+ super(BluetoothUtils.CYCLING_POWER_UUID, BluetoothUtils.CYCLING_POWER_MEASUREMENT_CHAR_UUID, observer);
+ }
+
+ @Override
+ protected SensorData createEmptySensorData(String address) {
+ return new SensorDataCyclingPower(address);
+ }
+
+ @Override
+ protected SensorDataCyclingPower parsePayload(String sensorName, String address, BluetoothGattCharacteristic characteristic) {
+ Integer cyclingPower = BluetoothUtils.parseCyclingPower(characteristic);
+
+ return cyclingPower != null ? new SensorDataCyclingPower(address, sensorName, cyclingPower) : null;
+ }
+ }
+
interface SensorDataObserver {
void onChanged(SensorData sensorData);
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
index 46547b7b1..9caba26ff 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
@@ -59,6 +59,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
private final BluetoothConnectionManager.HeartRate heartRate = new BluetoothConnectionManager.HeartRate(this);
private final BluetoothConnectionManager.CyclingCadence cyclingCadence = new BluetoothConnectionManager.CyclingCadence(this);
private final BluetoothConnectionManager.CyclingSpeed cyclingSpeed = new BluetoothConnectionManager.CyclingSpeed(this);
+ private final BluetoothConnectionManager.CyclingPower cyclingPower = new BluetoothConnectionManager.CyclingPower(this);
private final SensorDataSet sensorDataSet = new SensorDataSet();
@@ -82,6 +83,12 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
connect(cyclingSpeed, address);
}
+
+ if (PreferencesUtils.isKey(context, R.string.settings_sensor_bluetooth_cycling_power_key, key)) {
+ String address = PreferencesUtils.getBluetoothCyclingPowerSensorAddress(context);
+
+ connect(cyclingPower, address);
+ }
}
};
@@ -102,6 +109,8 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
public synchronized void stop() {
heartRate.disconnect();
cyclingCadence.disconnect();
+ cyclingSpeed.disconnect();
+ cyclingPower.disconnect();
sensorDataSet.clear();
diff --git a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
index e22e19f8a..81652c04f 100644
--- a/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
+++ b/src/main/java/de/dennisguse/opentracks/settings/SettingsActivity.java
@@ -20,6 +20,7 @@ import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
import de.dennisguse.opentracks.io.file.TrackFileFormat;
import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeCyclingCadenceAndSpeedPreference;
+import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeCyclingPowerPreference;
import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeHeartRatePreference;
import de.dennisguse.opentracks.settings.bluetooth.BluetoothLeSensorPreference;
import de.dennisguse.opentracks.util.ActivityUtils;
@@ -132,6 +133,8 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.HEART_RATE_SERVICE_UUID);
} else if (preference instanceof BluetoothLeCyclingCadenceAndSpeedPreference) {
dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.CYCLING_SPEED_CADENCE_SERVICE_UUID);
+ } else if (preference instanceof BluetoothLeCyclingPowerPreference) {
+ dialogFragment = BluetoothLeSensorPreference.BluetoothLeSensorPreferenceDialog.newInstance(preference.getKey(), BluetoothUtils.CYCLING_POWER_UUID);
}
if (dialogFragment != null) {
diff --git a/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeCyclingPowerPreference.java b/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeCyclingPowerPreference.java
new file mode 100644
index 000000000..486136bea
--- /dev/null
+++ b/src/main/java/de/dennisguse/opentracks/settings/bluetooth/BluetoothLeCyclingPowerPreference.java
@@ -0,0 +1,23 @@
+package de.dennisguse.opentracks.settings.bluetooth;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+public class BluetoothLeCyclingPowerPreference extends BluetoothLeSensorPreference {
+
+ public BluetoothLeCyclingPowerPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public BluetoothLeCyclingPowerPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public BluetoothLeCyclingPowerPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public BluetoothLeCyclingPowerPreference(Context context) {
+ super(context);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java b/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java
index 9c2dd5c22..37a5aab09 100644
--- a/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/util/BluetoothUtils.java
@@ -39,8 +39,11 @@ public class BluetoothUtils {
public static final UUID HEART_RATE_SERVICE_UUID = new UUID(0x180D00001000L, 0x800000805f9b34fbL);
public static final UUID HEART_RATE_MEASUREMENT_CHAR_UUID = new UUID(0x2A3700001000L, 0x800000805f9b34fbL);
+ public static final UUID CYCLING_POWER_UUID = new UUID(0x181800001000L, 0x800000805f9b34fbL);
+ public static final UUID CYCLING_POWER_MEASUREMENT_CHAR_UUID = new UUID(0x2A6300001000L, 0x800000805f9b34fbL);
+
public static final UUID CYCLING_SPEED_CADENCE_SERVICE_UUID = new UUID(0x181600001000L, 0x800000805f9b34fbL);
- public static final UUID CYCLING_SPPED_CADENCE_MEASUREMENT_CHAR_UUID = new UUID(0x2A5B00001000L, 0x800000805f9b34fbL);
+ public static final UUID CYCLING_SPEED_CADENCE_MEASUREMENT_CHAR_UUID = new UUID(0x2A5B00001000L, 0x800000805f9b34fbL);
private static final String TAG = BluetoothUtils.class.getSimpleName();
@@ -62,7 +65,7 @@ public class BluetoothUtils {
}
public static Integer parseHeartRate(BluetoothGattCharacteristic characteristic) {
- //DOCUMENTATION https://www.bluetooth.com/specifications/gatt/characteristics/
+ //DOCUMENTATION https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.heart_rate_measurement.xml
byte[] raw = characteristic.getValue();
if (raw.length == 0) {
return null;
@@ -79,10 +82,21 @@ public class BluetoothUtils {
return null;
}
+ public static Integer 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 < 4) {
+ return null;
+ }
+
+ return characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT16, 2);
+ }
+
/**
* Documentation: https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=261449
*/
public static SensorDataCycling.CadenceAndSpeed 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) {
return null;
diff --git a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
index 1fa437942..9b00dcece 100644
--- a/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
+++ b/src/main/java/de/dennisguse/opentracks/util/PreferencesUtils.java
@@ -262,6 +262,15 @@ public class PreferencesUtils {
return getInt(context, R.string.settings_sensor_bluetooth_cycling_speed_wheel_circumference_key, DEFAULT);
}
+ public static boolean isBluetoothCyclingPowerSensorAddressNone(Context context) {
+ return isBluetoothSensorAddressNone(context, getBluetoothCyclingPowerSensorAddress(context));
+ }
+
+ public static String getBluetoothCyclingPowerSensorAddress(Context context) {
+ return getString(context, R.string.settings_sensor_bluetooth_cycling_power_key, getBluetoothSensorAddressNone(context));
+ }
+
+
public static boolean shouldShowStatsOnLockscreen(Context context) {
final boolean STATS_SHOW_ON_LOCKSCREEN_DEFAULT = context.getResources().getBoolean(R.bool.stats_show_on_lockscreen_while_recording_default);
return getBoolean(context, R.string.stats_show_on_lockscreen_while_recording_key, STATS_SHOW_ON_LOCKSCREEN_DEFAULT);
diff --git a/src/main/res/layout/statistics_recording.xml b/src/main/res/layout/statistics_recording.xml
index ebc79b33e..94d8b1b48 100644
--- a/src/main/res/layout/statistics_recording.xml
+++ b/src/main/res/layout/statistics_recording.xml
@@ -487,5 +487,47 @@
app:layout_constraintRight_toLeftOf="@+id/guideline3"
app:layout_constraintTop_toBottomOf="@+id/stats_sensor_cadence_value" />
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml
index 0bdbefe06..e3403afa0 100644
--- a/src/main/res/values/colors.xml
+++ b/src/main/res/values/colors.xml
@@ -22,10 +22,10 @@ limitations under the License.
#40E88A70
#FF0066FF
#40C8E0FF
- #FF401465
- #40401465
#FF0066FF
#40C8E0FF
+ #FF7A26C0
+ #407A26C0
@android:color/holo_orange_dark
#55FF8800
diff --git a/src/main/res/values/do_not_translate.xml b/src/main/res/values/do_not_translate.xml
index 4cd700015..e29c1cbd8 100644
--- a/src/main/res/values/do_not_translate.xml
+++ b/src/main/res/values/do_not_translate.xml
@@ -26,6 +26,7 @@ limitations under the License.
BPM
RPM
+ W
-
diff --git a/src/main/res/values/settings.xml b/src/main/res/values/settings.xml
index 515154264..ad77abd22 100644
--- a/src/main/res/values/settings.xml
+++ b/src/main/res/values/settings.xml
@@ -21,6 +21,7 @@
bluetoothSensor
bluetoothCyclingCadenceSensor
bluetoothCyclingSpeedSensor
+ bluetoothCyclingPowerSensor
NONE
bluetoothCyclingSpeedWheelCircumference
diff --git a/src/main/res/xml/settings.xml b/src/main/res/xml/settings.xml
index 8e23c55ab..e792e4d08 100644
--- a/src/main/res/xml/settings.xml
+++ b/src/main/res/xml/settings.xml
@@ -131,6 +131,10 @@ limitations under the License.
android:defaultValue="@string/sensor_type_value_none"
android:key="@string/settings_sensor_bluetooth_cycling_cadence_key"
android:title="@string/sensor_state_cadence" />
+