mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
extend support for non-GPS activities
This enhances the general GB code _without_ the device specific adjustments required to actually display values: - chart elevation even if the activity has no GPS recording (e.g. treadmill and floor climbing) - added distance chart - added stride chart - added step length chart - added body energy chart - 24/7 energy level - added stamina chart - activity specific endurance capacity - added N2 load (Nitrogen) chart for diving - added CNS toxicity (Central Nervous System) chart for diving - added oxygen toxicity summary for diving - added surface interval summary for diving
This commit is contained in:
committed by
José Rebelo
parent
bad2d6f842
commit
9344940260
+305
-37
@@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2025-2026 José Rebelo, a0z, Me7c7, punchdeerflyscorpion, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.workouts.charts;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_BPM;
|
||||
@@ -8,6 +24,8 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_METERS_PER_SECOND;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_MINUTES_PER_100_METERS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_MINUTES_PER_KM;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_MM;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_PERCENTAGE;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_SECONDS_PER_100_METERS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_SECONDS_PER_KM;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_SPM;
|
||||
@@ -48,17 +66,39 @@ public class DefaultWorkoutCharts {
|
||||
final ActivityKind.CycleUnit cycleUnit = ActivityKind.getCycleUnit(activityKind);
|
||||
final List<WorkoutChart> charts = new LinkedList<>();
|
||||
final TimestampTranslation tsTranslation = new TimestampTranslation();
|
||||
final List<Entry> heartRateDataPoints = new ArrayList<>();
|
||||
final List<Entry> speedDataPoints = new ArrayList<>();
|
||||
final List<Entry> cadenceDataPoints = new ArrayList<>();
|
||||
final List<Entry> elevationDataPoints = new ArrayList<>();
|
||||
final List<Entry> powerDataPoints = new ArrayList<>();
|
||||
final List<Entry> respiratoryRatePoints = new ArrayList<>();
|
||||
final List<Entry> temperatureDataPoints = new ArrayList<>();
|
||||
final List<Entry> depthDataPoints = new ArrayList<>();
|
||||
final int initalCapacity = activityPoints.size();
|
||||
final List<Entry> heartRateDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> speedDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> cadenceDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> elevationDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> powerDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> respiratoryRatePoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> temperatureDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> depthDataPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> distancePoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> stridePoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> staminaPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> bodyEnergyPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> stepLengthPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> n2LoadPoints = new ArrayList<>(initalCapacity);
|
||||
final List<Entry> cnsToxicityPoints = new ArrayList<>(initalCapacity);
|
||||
|
||||
// some activities / devices provide all points with zero values
|
||||
boolean hasSpeedValues = false;
|
||||
boolean hasCadenceValues = false;
|
||||
boolean hasElevationValues = false;
|
||||
boolean hasPowerValues = false;
|
||||
boolean hasRespiratoryRateValues = false;
|
||||
boolean hasTemperatureValues = false;
|
||||
boolean hasDepthValues = false;
|
||||
boolean hasDistanceValues = false;
|
||||
boolean hasStrideValues = false;
|
||||
boolean hasBodyEnergyValues = false;
|
||||
boolean hasStaminaValues = false;
|
||||
boolean hasStepLengthValues = false;
|
||||
boolean hasN2LoadValues = false;
|
||||
boolean hasCnsToxicityValues = false;
|
||||
|
||||
final Accumulator cadenceAccumulator = new Accumulator();
|
||||
final Accumulator temperatureAccumulator = new Accumulator();
|
||||
|
||||
@@ -67,47 +107,107 @@ public class DefaultWorkoutCharts {
|
||||
final long tsShorten = tsTranslation.shorten((int) point.getTime().getTime());
|
||||
|
||||
// HR
|
||||
if (point.getHeartRate() > 0) {
|
||||
heartRateDataPoints.add(new Entry(tsShorten, point.getHeartRate()));
|
||||
final int heartRate = point.getHeartRate();
|
||||
if (heartRate > 0) {
|
||||
heartRateDataPoints.add(new Entry(tsShorten, heartRate));
|
||||
}
|
||||
|
||||
// Elevation
|
||||
if (point.getLocation() != null && point.getLocation().hasAltitude()) {
|
||||
elevationDataPoints.add(new Entry(tsShorten, (float) point.getLocation().getAltitude()));
|
||||
if (point.getLocation().getAltitude() != 0) {
|
||||
// Some devices provide all points at zero
|
||||
hasElevationValues = true;
|
||||
}
|
||||
final double elevation = point.getAltitude();
|
||||
if (elevation > GPSCoordinate.UNKNOWN_ALTITUDE) {
|
||||
elevationDataPoints.add(new Entry(tsShorten, (float) elevation));
|
||||
hasElevationValues = hasElevationValues || (elevation != 0.0);
|
||||
}
|
||||
|
||||
// Speed
|
||||
speedDataPoints.add(new Entry(tsShorten, point.getSpeed()));
|
||||
if (!hasSpeedValues && point.getSpeed() > 0) {
|
||||
hasSpeedValues = true;
|
||||
final float speed = point.getSpeed();
|
||||
if(speed >= 0.0f) {
|
||||
speedDataPoints.add(new Entry(tsShorten, speed));
|
||||
hasSpeedValues = hasSpeedValues || (speed > 0.0f);
|
||||
}
|
||||
|
||||
// Cadence
|
||||
cadenceDataPoints.add(new Entry(tsShorten, point.getCadence()));
|
||||
cadenceAccumulator.add(point.getCadence());
|
||||
if (!hasCadenceValues && point.getCadence() > 0) {
|
||||
hasCadenceValues = true;
|
||||
final float cadence = point.getCadence();
|
||||
if(cadence >= 0.0f){
|
||||
cadenceDataPoints.add(new Entry(tsShorten, cadence));
|
||||
cadenceAccumulator.add(cadence);
|
||||
hasCadenceValues = hasCadenceValues || (cadence > 0.0f);
|
||||
}
|
||||
if (point.getPower() >= 0) {
|
||||
powerDataPoints.add(new Entry(tsShorten, (float) point.getPower()));
|
||||
|
||||
final float power = point.getPower();
|
||||
if (power >= 0.0f) {
|
||||
powerDataPoints.add(new Entry(tsShorten, power));
|
||||
hasPowerValues = hasPowerValues || (power > 0.0f);
|
||||
}
|
||||
if (point.getRespiratoryRate() >= 0) {
|
||||
respiratoryRatePoints.add(new Entry(tsShorten, point.getRespiratoryRate()));
|
||||
|
||||
final float respiratoryRate = point.getRespiratoryRate();
|
||||
if (respiratoryRate >= 0.0f) {
|
||||
respiratoryRatePoints.add(new Entry(tsShorten, respiratoryRate));
|
||||
hasRespiratoryRateValues = hasRespiratoryRateValues || (respiratoryRate > 0.0f);
|
||||
}
|
||||
|
||||
// Depth (diving activity)
|
||||
if (point.getDepth() > 0) {
|
||||
depthDataPoints.add(new Entry(tsShorten, (float) point.getDepth() * -1));
|
||||
final double depth = point.getDepth();
|
||||
if (depth >= 0.0) {
|
||||
depthDataPoints.add(new Entry(tsShorten, (float) -depth));
|
||||
hasDepthValues = hasDepthValues || (depth > 0.0);
|
||||
}
|
||||
|
||||
// Temperature
|
||||
if (point.getTemperature() > -273) {
|
||||
temperatureDataPoints.add(new Entry(tsShorten, (float) point.getTemperature()));
|
||||
temperatureAccumulator.add(point.getTemperature());
|
||||
final double temperature = point.getTemperature();
|
||||
if (temperature > -273) {
|
||||
temperatureDataPoints.add(new Entry(tsShorten, (float) temperature));
|
||||
temperatureAccumulator.add(temperature);
|
||||
hasTemperatureValues = hasTemperatureValues || (temperature != 0.0);
|
||||
}
|
||||
|
||||
// Distance
|
||||
final double distance = point.getDistance();
|
||||
if (distance >= 0.0) {
|
||||
distancePoints.add(new Entry(tsShorten, (float) distance));
|
||||
hasDistanceValues = hasDistanceValues || (distance > 0);
|
||||
}
|
||||
|
||||
// Stride
|
||||
final float stride = point.getStride();
|
||||
if (stride >= 0.0f) {
|
||||
stridePoints.add(new Entry(tsShorten, stride));
|
||||
hasStrideValues = hasStrideValues || (stride > 0.0f);
|
||||
}
|
||||
|
||||
// Body Energy
|
||||
final float bodyEnergy = point.getBodyEnergy();
|
||||
if (bodyEnergy >= 0.0f) {
|
||||
bodyEnergyPoints.add(new Entry(tsShorten, bodyEnergy));
|
||||
hasBodyEnergyValues = hasBodyEnergyValues || (bodyEnergy > 0.0f);
|
||||
}
|
||||
|
||||
// Stamina
|
||||
final float stamina = point.getStamina();
|
||||
if (stamina >= 0.0f) {
|
||||
staminaPoints.add(new Entry(tsShorten, stamina));
|
||||
hasStaminaValues = hasStaminaValues || (stamina > 0.0f);
|
||||
}
|
||||
|
||||
// Step Length
|
||||
final int stepLength = point.getStepLength();
|
||||
if (stepLength >= 0) {
|
||||
stepLengthPoints.add(new Entry(tsShorten, stepLength));
|
||||
hasStepLengthValues = hasStepLengthValues || (stepLength > 0);
|
||||
}
|
||||
|
||||
// CNS Toxicity
|
||||
final float cnsToxicity = point.getCnsToxicity();
|
||||
if (cnsToxicity >= 0.0f) {
|
||||
cnsToxicityPoints.add(new Entry(tsShorten, cnsToxicity));
|
||||
hasCnsToxicityValues = hasCnsToxicityValues || (cnsToxicity > 0.0f);
|
||||
}
|
||||
|
||||
// N2 Load
|
||||
final float n2Load = point.getN2Load();
|
||||
if (n2Load >= 0.0f) {
|
||||
n2LoadPoints.add(new Entry(tsShorten, n2Load));
|
||||
hasN2LoadValues = hasN2LoadValues || (n2Load > 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,22 +227,50 @@ public class DefaultWorkoutCharts {
|
||||
charts.add(createElevationChart(context, elevationDataPoints));
|
||||
}
|
||||
|
||||
if (!powerDataPoints.isEmpty()) {
|
||||
if (hasPowerValues && !powerDataPoints.isEmpty()) {
|
||||
charts.add(createPowerChart(context, powerDataPoints));
|
||||
}
|
||||
|
||||
if (!respiratoryRatePoints.isEmpty()) {
|
||||
if (hasRespiratoryRateValues && !respiratoryRatePoints.isEmpty()) {
|
||||
charts.add(createRespiratoryRateChart(context, respiratoryRatePoints));
|
||||
}
|
||||
|
||||
if (!depthDataPoints.isEmpty()) {
|
||||
if (hasDepthValues && !depthDataPoints.isEmpty()) {
|
||||
charts.add(createDepthChart(context, depthDataPoints));
|
||||
}
|
||||
|
||||
if (!temperatureDataPoints.isEmpty()) {
|
||||
if (hasTemperatureValues && !temperatureDataPoints.isEmpty()) {
|
||||
charts.add(createTemperatureChart(context, temperatureDataPoints, temperatureAccumulator));
|
||||
}
|
||||
|
||||
if (hasDistanceValues && !distancePoints.isEmpty()) {
|
||||
charts.add(createDistanceChart(context, distancePoints));
|
||||
}
|
||||
|
||||
if (hasStrideValues && !stridePoints.isEmpty()) {
|
||||
charts.add(createStrideChart(context, stridePoints));
|
||||
}
|
||||
|
||||
if (hasBodyEnergyValues && !bodyEnergyPoints.isEmpty()) {
|
||||
charts.add(createBodyEnergyChart(context, bodyEnergyPoints));
|
||||
}
|
||||
|
||||
if (hasStaminaValues && !staminaPoints.isEmpty()) {
|
||||
charts.add(createStaminaChart(context, staminaPoints));
|
||||
}
|
||||
|
||||
if (hasStepLengthValues && !stepLengthPoints.isEmpty()) {
|
||||
charts.add(createStepLengthChart(context, stepLengthPoints));
|
||||
}
|
||||
|
||||
if (hasCnsToxicityValues && !cnsToxicityPoints.isEmpty()) {
|
||||
charts.add(createCnsToxicityChart(context, cnsToxicityPoints));
|
||||
}
|
||||
|
||||
if (hasN2LoadValues && !n2LoadPoints.isEmpty()) {
|
||||
charts.add(createN2LoadChart(context, n2LoadPoints));
|
||||
}
|
||||
|
||||
return charts;
|
||||
}
|
||||
|
||||
@@ -338,12 +466,152 @@ public class DefaultWorkoutCharts {
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createDistanceChart(final Context context,
|
||||
final List<Entry> distancePoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.distance), getUnitString(context, UNIT_METERS));
|
||||
final LineDataSet dataset = createLineDataSet(context, distancePoints, label, ContextCompat.getColor(context, R.color.chart_line_distance));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_distance",
|
||||
context.getString(R.string.distance),
|
||||
ActivitySummaryEntries.GROUP_DISTANCE,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_METERS)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createStrideChart(final Context context,
|
||||
final List<Entry> stridePoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.stride), getUnitString(context, UNIT_MM));
|
||||
final LineDataSet dataset = createLineDataSet(context, stridePoints, label, ContextCompat.getColor(context, R.color.chart_line_stride));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_stride",
|
||||
context.getString(R.string.stride),
|
||||
ActivitySummaryEntries.GROUP_STEPS,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_MM)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createBodyEnergyChart(final Context context,
|
||||
final List<Entry> bodyEnergyPoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.body_energy), getUnitString(context, UNIT_PERCENTAGE));
|
||||
final LineDataSet dataset = createLineDataSet(context, bodyEnergyPoints, label, ContextCompat.getColor(context, R.color.chart_line_body_energy));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_body_energy",
|
||||
context.getString(R.string.body_energy),
|
||||
ActivitySummaryEntries.GROUP_TRAINING_EFFECT,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_PERCENTAGE)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createStaminaChart(final Context context,
|
||||
final List<Entry> staminaPoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.stamina), getUnitString(context, UNIT_PERCENTAGE));
|
||||
final LineDataSet dataset = createLineDataSet(context, staminaPoints, label, ContextCompat.getColor(context, R.color.chart_line_stamina));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_stamina",
|
||||
context.getString(R.string.stamina),
|
||||
ActivitySummaryEntries.GROUP_TRAINING_EFFECT,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_PERCENTAGE)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createStepLengthChart(final Context context,
|
||||
final List<Entry> stepLengthPoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.step_length), getUnitString(context, UNIT_MM));
|
||||
final LineDataSet dataset = createLineDataSet(context, stepLengthPoints, label, ContextCompat.getColor(context, R.color.chart_line_step_length));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_step_length",
|
||||
context.getString(R.string.step_length),
|
||||
ActivitySummaryEntries.GROUP_STEPS,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_MM)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createCnsToxicityChart(final Context context,
|
||||
final List<Entry> cnsToxicityPoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.diving_cns_toxicity), getUnitString(context, UNIT_PERCENTAGE));
|
||||
final LineDataSet dataset = createLineDataSet(context, cnsToxicityPoints, label, ContextCompat.getColor(context, R.color.chart_cns_toxicity));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_cns_toxicity",
|
||||
context.getString(R.string.diving_cns_toxicity),
|
||||
ActivitySummaryEntries.GROUP_DIVING,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_PERCENTAGE)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createN2LoadChart(final Context context,
|
||||
final List<Entry> n2LoadPoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.diving_nitrogen_load), getUnitString(context, UNIT_PERCENTAGE));
|
||||
final LineDataSet dataset = createLineDataSet(context, n2LoadPoints, label, ContextCompat.getColor(context, R.color.chart_n2_load));
|
||||
final ValueFormatter valueFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"chart_n2_load",
|
||||
context.getString(R.string.diving_nitrogen_load),
|
||||
ActivitySummaryEntries.GROUP_DIVING,
|
||||
new LineData(dataset),
|
||||
valueFormatter,
|
||||
getUnitString(context, UNIT_PERCENTAGE)
|
||||
);
|
||||
}
|
||||
|
||||
public static String getUnitString(final Context context, final String unit) {
|
||||
final int resId = context.getResources().getIdentifier(unit, "string", context.getPackageName());
|
||||
if (resId != 0) {
|
||||
return context.getString(resId);
|
||||
}
|
||||
return "";
|
||||
return unit;
|
||||
}
|
||||
|
||||
public static LineDataSet createLineDataSet(final Context context,
|
||||
|
||||
+44
-9
@@ -1,3 +1,19 @@
|
||||
/* Copyright (C) 2025-2026 José Rebelo, a0z, Me7c7, Martin Piatka, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData
|
||||
@@ -280,6 +296,8 @@ object ActivitySummaryGroup {
|
||||
ActivitySummaryEntries.END_N2,
|
||||
ActivitySummaryEntries.DIVE_NUMBER,
|
||||
ActivitySummaryEntries.BOTTOM_TIME,
|
||||
ActivitySummaryEntries.OXYGEN_TOXICITY,
|
||||
ActivitySummaryEntries.SURFACE_INTERVAL,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -315,6 +333,32 @@ object ActivitySummaryGroup {
|
||||
)
|
||||
)
|
||||
|
||||
// Distance
|
||||
put(ActivitySummaryEntries.GROUP_DISTANCE, listOf(
|
||||
ActivitySummaryEntries.DISTANCE_METERS
|
||||
))
|
||||
|
||||
// Steps
|
||||
put(ActivitySummaryEntries.GROUP_STEPS, listOf(
|
||||
ActivitySummaryEntries.AVG_GROUND_CONTACT_TIME,
|
||||
ActivitySummaryEntries.AVG_GROUND_CONTACT_TIME_BALANCE,
|
||||
ActivitySummaryEntries.AVG_VERTICAL_OSCILLATION,
|
||||
ActivitySummaryEntries.AVG_VERTICAL_RATIO,
|
||||
ActivitySummaryEntries.STANDING_COUNT,
|
||||
ActivitySummaryEntries.STANDING_TIME,
|
||||
ActivitySummaryEntries.STEPS,
|
||||
ActivitySummaryEntries.STEP_LENGTH_AVG,
|
||||
ActivitySummaryEntries.STEP_RATE_AVG,
|
||||
ActivitySummaryEntries.STEP_RATE_MAX,
|
||||
ActivitySummaryEntries.STEP_RATE_SUM,
|
||||
ActivitySummaryEntries.STEP_SPEED_LOSS,
|
||||
ActivitySummaryEntries.STEP_SPEED_LOSS_PERCENTAGE,
|
||||
ActivitySummaryEntries.STRIDE_AVG,
|
||||
ActivitySummaryEntries.STRIDE_MAX,
|
||||
ActivitySummaryEntries.STRIDE_MIN,
|
||||
ActivitySummaryEntries.STRIDE_TOTAL,
|
||||
))
|
||||
|
||||
// Other
|
||||
put(
|
||||
ActivitySummaryEntries.GROUP_OTHER, listOf<String>(
|
||||
@@ -323,15 +367,6 @@ object ActivitySummaryGroup {
|
||||
ActivitySummaryEntries.CALORIES_BURNT,
|
||||
ActivitySummaryEntries.CALORIES_TOTAL,
|
||||
ActivitySummaryEntries.CALORIES_RESTING,
|
||||
ActivitySummaryEntries.STRIDE_AVG,
|
||||
ActivitySummaryEntries.STRIDE_MAX,
|
||||
ActivitySummaryEntries.STRIDE_MIN,
|
||||
ActivitySummaryEntries.STEP_LENGTH_AVG,
|
||||
ActivitySummaryEntries.CADENCE_AVG,
|
||||
ActivitySummaryEntries.CADENCE_MAX,
|
||||
ActivitySummaryEntries.CADENCE_MIN,
|
||||
ActivitySummaryEntries.STEP_RATE_AVG,
|
||||
ActivitySummaryEntries.STEP_RATE_MAX,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2017-2024 Carsten Pfeiffer, Daniele Gobbetti, José Rebelo
|
||||
/* Copyright (C) 2017-2026 Carsten Pfeiffer, Daniele Gobbetti, José Rebelo, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@@ -16,37 +16,30 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
// https://www8.garmin.com/xmlschemas/TrackPointExtensionv1.xsd
|
||||
/*
|
||||
<trkpt lat="54.8591470" lon="-1.5754310">
|
||||
<ele>29.2</ele>
|
||||
<time>2015-07-26T07:43:42Z</time>
|
||||
<extensions>
|
||||
<gpxtpx:TrackPointExtension>
|
||||
<gpxtpx:atemp>11</gpxtpx:atemp>
|
||||
<gpxtpx:hr>92</gpxtpx:hr>
|
||||
<gpxtpx:cad>0</gpxtpx:cad>
|
||||
<gpxtpx:speed>0.5</gpxtpx:speed>
|
||||
</gpxtpx:TrackPointExtension>
|
||||
</extensions>
|
||||
</trkpt>
|
||||
*/
|
||||
public class ActivityPoint {
|
||||
private Date time;
|
||||
private GPSCoordinate location;
|
||||
private int heartRate;
|
||||
private float speed = -1;
|
||||
private int strideCm = -1;
|
||||
private int stride = -1;
|
||||
private int stepLength = -1;
|
||||
private int cadence = -1;
|
||||
private int power = -1;
|
||||
private float power = -1;
|
||||
private float respiratoryRate = -1;
|
||||
private double depth = -1;
|
||||
private double temperature = -273;
|
||||
private double distance = -1.0;
|
||||
private float bodyEnergy = -1.0f;
|
||||
private float stamina = -1.0f;
|
||||
private float cnsToxicity = -1.0f;
|
||||
private float n2Load = -1.0f;
|
||||
private double altitude = GPSCoordinate.UNKNOWN_ALTITUDE;
|
||||
|
||||
// e.g. to describe a pause during the activity
|
||||
private @Nullable String description;
|
||||
@@ -62,7 +55,7 @@ public class ActivityPoint {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Date time) {
|
||||
public void setTime(@NonNull Date time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@@ -75,36 +68,93 @@ public class ActivityPoint {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GPSCoordinate getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(GPSCoordinate location) {
|
||||
public void setLocation(@Nullable GPSCoordinate location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public double getAltitude() {
|
||||
if (altitude > GPSCoordinate.UNKNOWN_ALTITUDE) {
|
||||
return altitude;
|
||||
}
|
||||
if (location != null) {
|
||||
return location.getAltitude();
|
||||
}
|
||||
return GPSCoordinate.UNKNOWN_ALTITUDE;
|
||||
}
|
||||
|
||||
/// 24/7 energy level
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public float getBodyEnergy() {
|
||||
return bodyEnergy;
|
||||
}
|
||||
|
||||
/// endurance capacity when doing a specific activity
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public float getStamina() {
|
||||
return stamina;
|
||||
}
|
||||
|
||||
/// central nervous system (CNS) toxicity (e.g. Diving)
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public float getCnsToxicity() {
|
||||
return cnsToxicity;
|
||||
}
|
||||
|
||||
/// nitrogen (N2) tissue load (e.g. Diving)
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public float getN2Load() {
|
||||
return cnsToxicity;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public double getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setDistance(double distanceInMeter) {
|
||||
distance = distanceInMeter;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BPM
|
||||
public int getHeartRate() {
|
||||
return heartRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BPM
|
||||
public void setHeartRate(int heartRate) {
|
||||
this.heartRate = heartRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS_PER_SECOND
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS_PER_SECOND
|
||||
public void setSpeed(float speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public int getStrideCm() {
|
||||
return strideCm;
|
||||
/// distance from one foot landing to the same foot landing again
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public int getStride() {
|
||||
return stride;
|
||||
}
|
||||
|
||||
public void setStrideCm(int strideCm) {
|
||||
this.strideCm = strideCm;
|
||||
/// distance from one foot landing to the opposite foot landing
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public int getStepLength() {
|
||||
return stepLength;
|
||||
}
|
||||
|
||||
public int getCadence() {
|
||||
@@ -115,74 +165,127 @@ public class ActivityPoint {
|
||||
this.cadence = cadence;
|
||||
}
|
||||
|
||||
public int getPower() {
|
||||
/// @see ActivitySummaryEntries#UNIT_WATT
|
||||
public float getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public void setPower(final int power) {
|
||||
/// @see ActivitySummaryEntries#UNIT_WATT
|
||||
public void setPower(final float power) {
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BREATHS_PER_MIN
|
||||
public float getRespiratoryRate() {
|
||||
return respiratoryRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BREATHS_PER_MIN
|
||||
public void setRespiratoryRate(final float respiratoryRate) {
|
||||
this.respiratoryRate = respiratoryRate;
|
||||
}
|
||||
|
||||
public double getTemperature() {return temperature; }
|
||||
public void setTemperature(final double temperature) { this.temperature = temperature; }
|
||||
public double getDepth() {return depth; }
|
||||
public void setDepth(final double depth) { this.depth = depth; }
|
||||
/// @see ActivitySummaryEntries#UNIT_CELSIUS
|
||||
public double getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_CELSIUS
|
||||
public void setTemperature(final double temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public double getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setDepth(final double depth) {
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ActivityPoint that)) return false;
|
||||
return heartRate == that.heartRate &&
|
||||
Float.compare(speed, that.speed) == 0 &&
|
||||
strideCm == that.strideCm &&
|
||||
stride == that.stride &&
|
||||
cadence == that.cadence &&
|
||||
power == that.power &&
|
||||
Float.compare(power, that.power) == 0 &&
|
||||
Float.compare(respiratoryRate, that.respiratoryRate) == 0 &&
|
||||
Double.compare(depth, that.depth) == 0 &&
|
||||
Double.compare(temperature, that.temperature) == 0 &&
|
||||
Objects.equals(time, that.time) &&
|
||||
Objects.equals(location, that.location) &&
|
||||
Objects.equals(description, that.description);
|
||||
Objects.equals(description, that.description) &&
|
||||
Double.compare(distance, that.distance) == 0 &&
|
||||
Double.compare(altitude, that.altitude) == 0 &&
|
||||
Float.compare(bodyEnergy, that.bodyEnergy) == 0 &&
|
||||
Float.compare(stamina, that.stamina) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(time, location, heartRate, speed, strideCm, cadence, power, respiratoryRate, depth, temperature, description);
|
||||
return Objects.hash(time, location, heartRate, speed, stride, cadence, power, respiratoryRate, depth, temperature, description, distance, altitude, bodyEnergy, stamina);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private long timeMillis;
|
||||
private Date date;
|
||||
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
private double altitude = GPSCoordinate.UNKNOWN_ALTITUDE;
|
||||
@Nullable
|
||||
private String description;
|
||||
|
||||
private int heartRate;
|
||||
private float speed = -1;
|
||||
private int strideCm = -1;
|
||||
private int cadence = -1;
|
||||
private int power = -1;
|
||||
private float respiratoryRate = -1;
|
||||
private double depth = -1;
|
||||
private double temperature = -273;
|
||||
private GPSCoordinate location;
|
||||
private double latitude = Double.NaN;
|
||||
private double longitude = Double.NaN;
|
||||
private double altitude = Double.NaN;
|
||||
private double hdop = Double.NaN;
|
||||
private double distance = Double.NaN;
|
||||
|
||||
private int heartRate = Integer.MIN_VALUE;
|
||||
private float speed = Float.NaN;
|
||||
private int stride = Integer.MIN_VALUE;
|
||||
private int stepLength = Integer.MIN_VALUE;
|
||||
private int cadence = Integer.MIN_VALUE;
|
||||
private float power = Float.NaN;
|
||||
private float respiratoryRate = Float.NaN;
|
||||
private double depth = Double.NaN;
|
||||
private double temperature = Double.NaN;
|
||||
private float bodyEnergy = Float.NaN;
|
||||
private float stamina = Float.NaN;
|
||||
private float cnsToxicity = Float.NaN;
|
||||
private float n2Load = Float.NaN;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public Builder(long epocMilliSeconds) {
|
||||
date = new Date(epocMilliSeconds);
|
||||
}
|
||||
|
||||
public Builder(@NonNull Long epocMilliSeconds) {
|
||||
date = new Date(epocMilliSeconds);
|
||||
}
|
||||
|
||||
public Builder(@NonNull Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return timeMillis;
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
public void setTime(final long timeMillis) {
|
||||
this.timeMillis = timeMillis;
|
||||
public void setTime(long unixEpocMilliSeconds) {
|
||||
date = new Date(unixEpocMilliSeconds);
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
public void setTime(@NonNull Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public void setLatitude(@Nullable final Double latitude) {
|
||||
this.latitude = (latitude == null) ? Double.NaN : latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(final double latitude) {
|
||||
@@ -193,96 +296,311 @@ public class ActivityPoint {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(@Nullable final Double longitude) {
|
||||
this.longitude = (longitude == null) ? Double.NaN : longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(final double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public double getAltitude() {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setAltitude(@Nullable final Number altitude) {
|
||||
this.altitude = (altitude == null) ? Double.NaN : altitude.doubleValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setAltitude(final double altitude) {
|
||||
this.altitude = altitude;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BPM
|
||||
public int getHeartRate() {
|
||||
return heartRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BPM
|
||||
public void setHeartRate(@Nullable final Number heartRate) {
|
||||
this.heartRate = (heartRate == null) ? Integer.MIN_VALUE : heartRate.intValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BPM
|
||||
public void setHeartRate(final int heartRate) {
|
||||
this.heartRate = heartRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS_PER_SECOND
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS_PER_SECOND
|
||||
public void setSpeed(@Nullable final Number speed) {
|
||||
this.speed = (speed == null) ? Float.NaN : speed.floatValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS_PER_SECOND
|
||||
public void setSpeed(final float speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public int getStrideCm() {
|
||||
return strideCm;
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public int getStride() {
|
||||
return stride;
|
||||
}
|
||||
|
||||
public void setStrideCm(int strideCm) {
|
||||
this.strideCm = strideCm;
|
||||
/// distance from one foot landing to the same foot landing again
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public void setStride(@Nullable Number stride) {
|
||||
this.stride = (stride == null) ? Integer.MIN_VALUE : stride.intValue();
|
||||
}
|
||||
|
||||
/// distance from one foot landing to the same foot landing again
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public void setStride(int stride) {
|
||||
this.stride = stride;
|
||||
}
|
||||
|
||||
public int getCadence() {
|
||||
return cadence;
|
||||
}
|
||||
|
||||
public void setCadence(@Nullable final Number cadence) {
|
||||
this.cadence = (cadence == null) ? Integer.MIN_VALUE : cadence.intValue();
|
||||
}
|
||||
|
||||
public void setCadence(final int cadence) {
|
||||
this.cadence = cadence;
|
||||
}
|
||||
|
||||
public int getPower() {
|
||||
/// @see ActivitySummaryEntries#UNIT_WATT
|
||||
public float getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_WATT
|
||||
public void setPower(@Nullable final Number power) {
|
||||
this.power = (power == null) ? Integer.MIN_VALUE : power.intValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_WATT
|
||||
public void setPower(final int power) {
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BREATHS_PER_MIN
|
||||
public float getRespiratoryRate() {
|
||||
return respiratoryRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BREATHS_PER_MIN
|
||||
public void setRespiratoryRate(@Nullable final Number respiratoryRate) {
|
||||
this.respiratoryRate = (respiratoryRate == null) ? Float.NaN : respiratoryRate.floatValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_BREATHS_PER_MIN
|
||||
public void setRespiratoryRate(final float respiratoryRate) {
|
||||
this.respiratoryRate = respiratoryRate;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public double getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setDepth(@Nullable final Number depth) {
|
||||
this.depth = (depth == null) ? Double.NaN : depth.doubleValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setDepth(final double depth) {
|
||||
this.depth = depth;
|
||||
}
|
||||
|
||||
public void setLocation(@Nullable final GPSCoordinate location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_CELSIUS
|
||||
public double getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_CELSIUS
|
||||
public void setTemperature(@Nullable final Number temperature) {
|
||||
this.temperature = (temperature == null) ? Double.NaN : temperature.doubleValue();
|
||||
}
|
||||
|
||||
/// @see ActivitySummaryEntries#UNIT_CELSIUS
|
||||
public void setTemperature(final double temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
/// horizontal dilution of precision
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setHdop(@Nullable final Number hdop) {
|
||||
this.hdop = (hdop == null) ? Double.NaN : hdop.doubleValue();
|
||||
}
|
||||
|
||||
/// horizontal dilution of precision
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setHdop(final double hdop) {
|
||||
this.hdop = hdop;
|
||||
}
|
||||
|
||||
/// total traveled distance
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setDistance(@Nullable final Number distance) {
|
||||
this.distance = (distance == null) ? Double.NaN : distance.doubleValue();
|
||||
}
|
||||
|
||||
/// total traveled distance
|
||||
///
|
||||
/// @see ActivitySummaryEntries#UNIT_METERS
|
||||
public void setDistance(final double distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
/// e.g. to describe a pause during the activity
|
||||
public void setDescription(@Nullable String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/// 24/7 energy level
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setBodyEnergy(@Nullable Number bodyEnergy) {
|
||||
this.bodyEnergy = (bodyEnergy == null) ? Float.NaN : bodyEnergy.floatValue();
|
||||
}
|
||||
|
||||
/// 24/7 energy level
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setBodyEnergy(float bodyBattery) {
|
||||
this.bodyEnergy = bodyBattery;
|
||||
}
|
||||
|
||||
/// endurance capacity when doing a specific activity
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setStamina(@Nullable Number stamina) {
|
||||
this.stamina = (stamina == null) ? Float.NaN : stamina.floatValue();
|
||||
}
|
||||
|
||||
/// endurance capacity when doing a specific activity
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setStamina(float stamina) {
|
||||
this.stamina = stamina;
|
||||
}
|
||||
|
||||
/// distance from one foot landing to the opposite foot landing
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public void setStepLength(@Nullable Number stepLength){
|
||||
this.stepLength = (stepLength == null) ? Integer.MIN_VALUE : stepLength.intValue();
|
||||
}
|
||||
|
||||
/// distance from one foot landing to the opposite foot landing
|
||||
/// @see ActivitySummaryEntries#UNIT_MM
|
||||
public void setStepLength(int stepLength){
|
||||
this.stepLength = stepLength;
|
||||
}
|
||||
|
||||
/// central nervous system (CNS) toxicity (e.g. Diving)
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setCnsToxicity(@Nullable Number cnsToxicity) {
|
||||
this.cnsToxicity = (cnsToxicity == null) ? Float.NaN : cnsToxicity.floatValue();
|
||||
}
|
||||
|
||||
/// central nervous system (CNS) toxicity (e.g. Diving)
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setCnsToxicity(float cnsToxicity) {
|
||||
this.cnsToxicity = cnsToxicity;
|
||||
}
|
||||
|
||||
/// nitrogen (N2) tissue load (e.g. Diving)
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setN2Load(@Nullable Number n2Load) {
|
||||
this.n2Load = (n2Load == null) ? Float.NaN : n2Load.floatValue();
|
||||
}
|
||||
|
||||
/// nitrogen (N2) tissue load (e.g. Diving)
|
||||
/// @see ActivitySummaryEntries#UNIT_PERCENTAGE
|
||||
public void setN2Load(float n2Load) {
|
||||
this.n2Load = n2Load;
|
||||
}
|
||||
|
||||
|
||||
public ActivityPoint build() {
|
||||
final ActivityPoint activityPoint = new ActivityPoint();
|
||||
activityPoint.setTime(new Date(timeMillis));
|
||||
if (latitude != 0 && longitude != 0) {
|
||||
activityPoint.setLocation(new GPSCoordinate(longitude, latitude, altitude));
|
||||
final ActivityPoint activityPoint = new ActivityPoint(date);
|
||||
if (location != null) {
|
||||
activityPoint.setLocation(location);
|
||||
} else if (!(Double.isNaN(latitude) || Double.isNaN(longitude))) {
|
||||
final GPSCoordinate loc;
|
||||
if (altitude > GPSCoordinate.UNKNOWN_ALTITUDE) {
|
||||
loc = new GPSCoordinate(longitude, latitude, altitude);
|
||||
} else {
|
||||
loc = new GPSCoordinate(longitude, latitude);
|
||||
}
|
||||
if (hdop > 0.0) {
|
||||
loc.setHdop(hdop);
|
||||
}
|
||||
activityPoint.setLocation(loc);
|
||||
} else if (altitude > GPSCoordinate.UNKNOWN_ALTITUDE) {
|
||||
activityPoint.altitude = altitude;
|
||||
}
|
||||
activityPoint.setHeartRate(heartRate);
|
||||
activityPoint.setSpeed(speed);
|
||||
activityPoint.setCadence(cadence);
|
||||
activityPoint.setStrideCm(strideCm);
|
||||
activityPoint.setPower(power);
|
||||
activityPoint.setRespiratoryRate(respiratoryRate);
|
||||
activityPoint.setDepth(depth);
|
||||
activityPoint.setTemperature(temperature);
|
||||
|
||||
if (heartRate > Integer.MIN_VALUE) {
|
||||
activityPoint.setHeartRate(heartRate);
|
||||
}
|
||||
if (!Float.isNaN(speed)) {
|
||||
activityPoint.setSpeed(speed);
|
||||
}
|
||||
if (cadence > Integer.MIN_VALUE) {
|
||||
activityPoint.setCadence(cadence);
|
||||
}
|
||||
if (stride > Integer.MIN_VALUE) {
|
||||
activityPoint.stride = stride;
|
||||
}
|
||||
if (!Float.isNaN(power)) {
|
||||
activityPoint.setPower(power);
|
||||
}
|
||||
if (!Float.isNaN(respiratoryRate)) {
|
||||
activityPoint.setRespiratoryRate(respiratoryRate);
|
||||
}
|
||||
if (!Double.isNaN(depth)) {
|
||||
activityPoint.setDepth(depth);
|
||||
}
|
||||
if (!Double.isNaN(temperature)) {
|
||||
activityPoint.setTemperature(temperature);
|
||||
}
|
||||
if (description != null && description.length() > 0) {
|
||||
activityPoint.setDescription(description);
|
||||
}
|
||||
if (!Double.isNaN(distance)) {
|
||||
activityPoint.setDistance(distance);
|
||||
}
|
||||
if(!Float.isNaN(bodyEnergy)){
|
||||
activityPoint.bodyEnergy = bodyEnergy;
|
||||
}
|
||||
if(!Float.isNaN(stamina)){
|
||||
activityPoint.stamina = stamina;
|
||||
}
|
||||
if(stepLength > Integer.MIN_VALUE){
|
||||
activityPoint.stepLength = stepLength;
|
||||
}
|
||||
if(!Float.isNaN(cnsToxicity)){
|
||||
activityPoint.cnsToxicity = cnsToxicity;
|
||||
}
|
||||
if(!Float.isNaN(n2Load)){
|
||||
activityPoint.n2Load = n2Load;
|
||||
}
|
||||
|
||||
return activityPoint;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -257,6 +257,7 @@ public class ActivitySummaryEntries {
|
||||
public static final String UNIT_NAUTICAL_MILES = "nautical_miles";
|
||||
public static final String UNIT_KNOTS = "knots";
|
||||
public static final String UNIT_CELSIUS = "unit_celsius";
|
||||
public static final String UNIT_OXYGEN_TOXICITY_UNITs = "unit_oxygen_toxicity_units";
|
||||
|
||||
public static final String GROUP_PACE = "Pace";
|
||||
public static final String GROUP_ACTIVITY = "Activity";
|
||||
@@ -280,6 +281,8 @@ public class ActivitySummaryEntries {
|
||||
public static final String GROUP_DIVING = "activity_type_diving";
|
||||
public static final String GROUP_RECOVERY_HEART_RATE = "recovery_heart_rate";
|
||||
public static final String GROUP_MOVEMENT_EVALUATION = "movement_evaluation";
|
||||
public static final String GROUP_DISTANCE = "Distance";
|
||||
public static final String GROUP_STEPS = "Steps";
|
||||
public static final String AVG_DEPTH = "diving_avg_depth";
|
||||
public static final String START_CNS = "diving_start_cns";
|
||||
public static final String END_CNS = "diving_end_cns";
|
||||
@@ -287,6 +290,8 @@ public class ActivitySummaryEntries {
|
||||
public static final String END_N2 = "diving_end_n2";
|
||||
public static final String DIVE_NUMBER = "dive_number";
|
||||
public static final String BOTTOM_TIME = "diving_bottom_time";
|
||||
public static final String OXYGEN_TOXICITY = "diving_oxygen_toxicity";
|
||||
public static final String SURFACE_INTERVAL = "diving_surface_interval";
|
||||
|
||||
// DIVING parameters
|
||||
public static final String MAX_DEPTH = "diving_maximum_diving_depth";
|
||||
|
||||
+1
-1
@@ -316,7 +316,7 @@ public class ZeppOsActivityDetailsParser extends AbstractHuamiActivityDetailsPar
|
||||
final short pace = buf.getShort(); // sec/km
|
||||
|
||||
activityPointBuilder.setCadence(cadence);
|
||||
activityPointBuilder.setStrideCm(stride);
|
||||
activityPointBuilder.setStride(stride * 10.0f);
|
||||
if (pace != 0) {
|
||||
activityPointBuilder.setSpeed(1000f / pace); // s/km -> m/s
|
||||
}
|
||||
|
||||
@@ -102,6 +102,13 @@
|
||||
<color name="chart_line_stroke_rate" type="color">#6495ED</color>
|
||||
<color name="chart_highline_dolor" type="color">#ffff8800</color>
|
||||
<color name="chart_line_depth" type="color">#ff4040ff</color>
|
||||
<color name="chart_line_distance" type="color">#88FF88</color>
|
||||
<color name="chart_line_stride" type="color">#FF8888</color>
|
||||
<color name="chart_line_body_energy" type="color">#884088</color>
|
||||
<color name="chart_line_stamina" type="color">#8888FF</color>
|
||||
<color name="chart_line_step_length" type="color">#FF4088</color>
|
||||
<color name="chart_cns_toxicity" type="color">#FF4040</color>
|
||||
<color name="chart_n2_load" type="color">#FF8840</color>
|
||||
|
||||
<attr name="row_separator" format="color" />
|
||||
<color name="alternate_row_background_light">#FFEDEDED</color>
|
||||
|
||||
@@ -1056,6 +1056,14 @@
|
||||
<string name="respiratoryrate">Respiratory Rate</string>
|
||||
<string name="active_calories">Active calories</string>
|
||||
<string name="distance">Distance</string>
|
||||
<string name="stride">Stride</string>
|
||||
<string name="stamina">Stamina</string>
|
||||
<string name="step_length">Step Length</string>
|
||||
<string name="diving_cns_toxicity">CNS toxicity</string>
|
||||
<string name="diving_nitrogen_load">Nitrogen load</string>
|
||||
<string name="diving_oxygen_toxicity">Oxygen toxicity</string>
|
||||
<string name="unit_oxygen_toxicity_units">OTU</string>
|
||||
<string name="diving_surface_interval">Surface interval</string>
|
||||
<string name="clock">Clock</string>
|
||||
<string name="heart_rate">Heart rate</string>
|
||||
<string name="hr_resting">Resting</string>
|
||||
|
||||
Reference in New Issue
Block a user