Skip to content

Commit

Permalink
Add max power stats
Browse files Browse the repository at this point in the history
  • Loading branch information
quaelnix authored and dennisguse committed Sep 13, 2023
1 parent e130039 commit cf9b432
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -869,12 +869,14 @@ public SensorStatistics getSensorStats(@NonNull Track.Id trackId) {
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 MAX_POWER_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_MAX_POWER);
final int AVG_POWER_INDEX = cursor.getColumnIndexOrThrow(TrackPointsColumns.ALIAS_AVG_POWER);
sensorStatistics = new SensorStatistics(
!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(MAX_POWER_INDEX) ? Power.of(cursor.getFloat(MAX_POWER_INDEX)) : null,
!cursor.isNull(AVG_POWER_INDEX) ? Power.of(cursor.getFloat(AVG_POWER_INDEX)) : null
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class CustomContentProvider extends ContentProvider {

/**
* The string representing the query that compute sensor stats from trackpoints table.
* It computes the average for heart rate, cadence, and power (duration-based average) and the maximum for heart rate and cadence.
* It computes the average for heart rate, cadence and power (duration-based average) and the maximum for heart rate, cadence and power.
* Finally, it ignores manual pause (SEGMENT_START_MANUAL).
*/
private final String SENSOR_STATS_QUERY =
Expand All @@ -86,7 +86,9 @@ public class CustomContentProvider extends ContentProvider {

"SUM(t." + TrackPointsColumns.SENSOR_POWER + " * (COALESCE(MAX(t." + TrackPointsColumns.TIME + ", (SELECT time_value FROM time_select)), t." + TrackPointsColumns.TIME + ") - t." + TrackPointsColumns.TIME + ")) " +
"/ " +
"SUM(COALESCE(MAX(t." + TrackPointsColumns.TIME + ", (SELECT time_value FROM time_select)), t." + TrackPointsColumns.TIME + ") - t." + TrackPointsColumns.TIME + ") " + TrackPointsColumns.ALIAS_AVG_POWER + " " +
"SUM(COALESCE(MAX(t." + TrackPointsColumns.TIME + ", (SELECT time_value FROM time_select)), t." + TrackPointsColumns.TIME + ") - t." + TrackPointsColumns.TIME + ") " + TrackPointsColumns.ALIAS_AVG_POWER + ", " +

"MAX(t." + TrackPointsColumns.SENSOR_POWER + ") " + TrackPointsColumns.ALIAS_MAX_POWER + " " +

"FROM " + TrackPointsColumns.TABLE_NAME + " t " +
"WHERE t." + TrackPointsColumns.TRACKID + " = ? " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public interface TrackPointsColumns extends BaseColumns {
String ALIAS_AVG_CADENCE = "avg_cadence";
String ALIAS_MAX_CADENCE = "max_cadence";
String ALIAS_AVG_POWER = "avg_power";
String ALIAS_MAX_POWER = "max_power";

String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,12 @@ private void updateSensorUI() {
viewBinding.statsAvgCadenceValue.setText(avgRPM);
}
if (sensorStatistics.hasPower()) {
String W = String.valueOf(Math.round(sensorStatistics.getAvgPower().getW()));
String maxW = String.valueOf(Math.round(sensorStatistics.getMaxPower().getW()));
String avgW = String.valueOf(Math.round(sensorStatistics.getAvgPower().getW()));

viewBinding.statsPowerGroup.setVisibility(View.VISIBLE);
viewBinding.statsPowerValue.setText(W);
viewBinding.statsMaxPowerValue.setText(maxW);
viewBinding.statsAvgPowerValue.setText(avgW);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ public class SensorStatistics {
private final HeartRate avgHr;
private final Cadence maxCadence;
private final Cadence avgCadence;
private final Power maxPower;
private final Power avgPower;

public SensorStatistics(HeartRate maxHr, HeartRate avgHr, Cadence maxCadence, Cadence avgCadence, Power avgPower) {
public SensorStatistics(HeartRate maxHr, HeartRate avgHr, Cadence maxCadence, Cadence avgCadence, Power maxPower, Power avgPower) {
this.maxHr = maxHr;
this.avgHr = avgHr;
this.maxCadence = maxCadence;
this.avgCadence = avgCadence;
this.maxPower = maxPower;
this.avgPower = avgPower;
}

Expand Down Expand Up @@ -47,6 +49,10 @@ public boolean hasPower() {
return avgPower != null;
}

public Power getMaxPower() {
return maxPower;
}

public Power getAvgPower() {
return avgPower;
}
Expand Down
54 changes: 43 additions & 11 deletions src/main/res/layout/statistics_recorded.xml
Original file line number Diff line number Diff line change
Expand Up @@ -584,53 +584,85 @@
app:layout_constraintEnd_toStartOf="@id/guideline3"
app:layout_constraintTop_toBottomOf="@id/stats_cadence_barrier" />

<!-- Sensors data -->
<androidx.constraintlayout.widget.Group
android:id="@+id/stats_power_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="stats_power_horizontal_line,stats_power_label,stats_power_value,stats_power_unit" />
app:constraint_referenced_ids="stats_power_horizontal_line,stats_max_power_label,stats_max_power_value,stats_max_power_unit,stats_avg_power_label,stats_avg_power_value,stats_avg_power_unit" />

<TextView
android:id="@+id/stats_power_label"
android:id="@+id/stats_max_power_label"
style="@style/TextAppearance.OpenTracks.PrimaryHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sensor_state_power_avg"
android:text="@string/sensor_state_power_max"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="@id/guideline"
app:layout_constraintEnd_toStartOf="@id/guideline2"
app:layout_constraintTop_toBottomOf="@id/stats_power_horizontal_line" />

<TextView
android:id="@+id/stats_power_value"
android:id="@+id/stats_max_power_value"
style="@style/TextAppearance.OpenTracks.PrimaryValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:value="@string/value_unknown"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/guideline"
app:layout_constraintEnd_toStartOf="@id/stats_power_unit"
app:layout_constraintTop_toBottomOf="@id/stats_power_label"
app:layout_constraintEnd_toStartOf="@id/stats_max_power_unit"
app:layout_constraintTop_toBottomOf="@id/stats_max_power_label"
tools:text="100" />

<TextView
android:id="@+id/stats_power_unit"
android:id="@+id/stats_max_power_unit"
style="@style/TextAppearance.OpenTracks.PrimaryUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sensor_state_power_unit"
app:layout_constraintBottom_toBottomOf="@id/stats_power_value"
app:layout_constraintStart_toEndOf="@id/stats_power_value"
app:layout_constraintBottom_toBottomOf="@id/stats_max_power_value"
app:layout_constraintStart_toEndOf="@id/stats_max_power_value"
app:layout_constraintEnd_toStartOf="@id/guideline2" />

<TextView
android:id="@+id/stats_avg_power_label"
style="@style/TextAppearance.OpenTracks.PrimaryHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sensor_state_power_avg"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toEndOf="@id/guideline2"
app:layout_constraintEnd_toEndOf="@id/guideline3"
app:layout_constraintTop_toBottomOf="@id/stats_power_horizontal_line" />

<TextView
android:id="@+id/stats_avg_power_value"
style="@style/TextAppearance.OpenTracks.PrimaryValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:value="@string/value_unknown"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/guideline2"
app:layout_constraintEnd_toStartOf="@id/stats_avg_power_unit"
app:layout_constraintTop_toBottomOf="@id/stats_avg_power_label"
tools:text="100" />

<TextView
android:id="@+id/stats_avg_power_unit"
style="@style/TextAppearance.OpenTracks.PrimaryUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sensor_state_power_unit"
app:layout_constraintBottom_toBottomOf="@id/stats_avg_power_value"
app:layout_constraintStart_toEndOf="@id/stats_avg_power_value"
app:layout_constraintEnd_toStartOf="@id/guideline3" />

<androidx.constraintlayout.widget.Barrier
android:id="@+id/stats_power_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="stats_power_value" />
app:constraint_referenced_ids="stats_max_power_value,stats_avg_power_value" />

<!-- Horizontal Line -->
<View
Expand Down
1 change: 1 addition & 0 deletions src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ limitations under the License.
<string name="sensor_state_heart_rate_value">%1$d bpm</string>
<string name="sensor_state_power">Power</string>
<string name="sensor_state_power_avg">Avg Power</string>
<string name="sensor_state_power_max">Max Power</string>
<string name="sensor_state_power_unit">W</string>
<string name="sensor_could_not_scan">Could not scan for Bluetooth devices (error %1$i).</string>
<string name="bluetooth_disabled">Please enable Bluetooth.</string>
Expand Down

0 comments on commit cf9b432

Please sign in to comment.