mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Garmin: extend support for non-GPS activities
- 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 - adjusted dive summary layout
This commit is contained in:
committed by
José Rebelo
parent
5b2f982509
commit
bde914fad2
+12
-6
@@ -603,6 +603,12 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
summaryData.add(TRAINING_LOAD, safeRound(session.getTrainingLoadPeak()), UNIT_NONE);
|
||||
|
||||
if (diveSummary != null) {
|
||||
if (diveSummary.getDiveNumber() != null) {
|
||||
summaryData.add(DIVE_NUMBER, diveSummary.getDiveNumber(), UNIT_NONE);
|
||||
}
|
||||
if (diveSummary.getBottomTime() != null) {
|
||||
summaryData.add(BOTTOM_TIME, diveSummary.getBottomTime(), UNIT_SECONDS);
|
||||
}
|
||||
if (diveSummary.getAvgDepth() != null) {
|
||||
summaryData.add(AVG_DEPTH, diveSummary.getAvgDepth(), UNIT_METERS);
|
||||
}
|
||||
@@ -610,22 +616,22 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
summaryData.add(MAX_DEPTH, diveSummary.getMaxDepth(), UNIT_METERS);
|
||||
}
|
||||
if (diveSummary.getStartCns() != null) {
|
||||
summaryData.add(START_CNS, diveSummary.getStartCns(), UNIT_PERCENTAGE);
|
||||
summaryData.add(START_CNS, diveSummary.getStartCns(), UNIT_PERCENTAGE, true);
|
||||
}
|
||||
if (diveSummary.getEndCns() != null) {
|
||||
summaryData.add(END_CNS, diveSummary.getEndCns(), UNIT_PERCENTAGE);
|
||||
}
|
||||
if (diveSummary.getStartN2() != null) {
|
||||
summaryData.add(START_N2, diveSummary.getStartN2(), UNIT_PERCENTAGE);
|
||||
summaryData.add(START_N2, diveSummary.getStartN2(), UNIT_PERCENTAGE, true);
|
||||
}
|
||||
if (diveSummary.getEndN2() != null) {
|
||||
summaryData.add(END_N2, diveSummary.getEndN2(), UNIT_PERCENTAGE);
|
||||
}
|
||||
if (diveSummary.getDiveNumber() != null) {
|
||||
summaryData.add(DIVE_NUMBER, diveSummary.getDiveNumber(), UNIT_NONE);
|
||||
if (diveSummary.getO2Toxicity() != null) {
|
||||
summaryData.add(OXYGEN_TOXICITY, diveSummary.getO2Toxicity(), UNIT_OXYGEN_TOXICITY_UNITs);
|
||||
}
|
||||
if (diveSummary.getBottomTime() != null) {
|
||||
summaryData.add(BOTTOM_TIME, diveSummary.getBottomTime(), UNIT_SECONDS);
|
||||
if (diveSummary.getSurfaceInterval() != null) {
|
||||
summaryData.add(SURFACE_INTERVAL, diveSummary.getSurfaceInterval(), UNIT_SECONDS);
|
||||
}
|
||||
}
|
||||
summaryData.add(TEMPERATURE_MIN, session.getMinTemperature(), UNIT_CELSIUS);
|
||||
|
||||
+2
@@ -597,6 +597,8 @@ public class NativeFITMessage {
|
||||
new FieldDefinitionPrimitive(127, BaseType.SINT32, "ascent_rate", 1000, 0), // m/s
|
||||
new FieldDefinitionPrimitive(129, BaseType.UINT8, "po2", 100, 0), // %
|
||||
new FieldDefinitionPrimitive(136, BaseType.UINT8, "wrist_heart_rate"),
|
||||
new FieldDefinitionPrimitive(137, BaseType.UINT8, "stamina_potential"), // %
|
||||
new FieldDefinitionPrimitive(138, BaseType.UINT8, "stamina"), // %
|
||||
new FieldDefinitionPrimitive(139, BaseType.UINT16, "core_temperature", 100, 0), // °C
|
||||
new FieldDefinitionPrimitive(143, BaseType.UINT8, "body_battery"),
|
||||
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
|
||||
|
||||
+56
-33
@@ -18,10 +18,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition;
|
||||
@@ -458,6 +455,16 @@ public class FitRecord extends RecordData {
|
||||
return getFieldByNumber(136, Integer.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getStaminaPotential() {
|
||||
return getFieldByNumber(137, Integer.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getStamina() {
|
||||
return getFieldByNumber(138, Integer.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Float getCoreTemperature() {
|
||||
return getFieldByNumber(139, Float.class);
|
||||
@@ -896,6 +903,16 @@ public class FitRecord extends RecordData {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setStaminaPotential(final Integer value) {
|
||||
setFieldByNumber(137, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setStamina(final Integer value) {
|
||||
setFieldByNumber(138, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCoreTemperature(final Float value) {
|
||||
setFieldByNumber(139, value);
|
||||
return this;
|
||||
@@ -925,37 +942,43 @@ public class FitRecord extends RecordData {
|
||||
// manual changes below
|
||||
|
||||
public ActivityPoint toActivityPoint() {
|
||||
final ActivityPoint activityPoint = new ActivityPoint();
|
||||
activityPoint.setTime(new Date(getComputedTimestamp() * 1000L));
|
||||
if (getLatitude() != null && getLongitude() != null) {
|
||||
activityPoint.setLocation(new GPSCoordinate(
|
||||
getLongitude(),
|
||||
getLatitude(),
|
||||
getEnhancedAltitude() != null ? getEnhancedAltitude() : GPSCoordinate.UNKNOWN_ALTITUDE
|
||||
));
|
||||
}
|
||||
if (getHeartRate() != null) {
|
||||
activityPoint.setHeartRate(getHeartRate());
|
||||
}
|
||||
if (getEnhancedSpeed() != null) {
|
||||
activityPoint.setSpeed(getEnhancedSpeed().floatValue());
|
||||
}
|
||||
if (getCadence() != null) {
|
||||
activityPoint.setCadence(getCadence());
|
||||
}
|
||||
if (getPower() != null) {
|
||||
activityPoint.setPower(getPower());
|
||||
}
|
||||
if (getEnhancedRespirationRate() != null) {
|
||||
activityPoint.setRespiratoryRate(getEnhancedRespirationRate());
|
||||
}
|
||||
if (getTemperature() != null) {
|
||||
activityPoint.setTemperature(getTemperature());
|
||||
}
|
||||
if (getDepth() != null) {
|
||||
activityPoint.setDepth(getDepth());
|
||||
final ActivityPoint.Builder builder = new ActivityPoint.Builder(getComputedTimestamp() * 1000L);
|
||||
builder.setBodyEnergy(getBodyBattery());
|
||||
builder.setCadence(getCadence());
|
||||
builder.setCnsToxicity(getCnsLoad());
|
||||
builder.setDepth(getDepth());
|
||||
builder.setDistance(getDistance());
|
||||
builder.setHdop(getGpsAccuracy());
|
||||
builder.setHeartRate(getHeartRate());
|
||||
builder.setLatitude(getLatitude());
|
||||
builder.setLongitude(getLongitude());
|
||||
builder.setN2Load(getN2Load());
|
||||
builder.setPower(getPower());
|
||||
builder.setStamina(getStamina());
|
||||
builder.setStride(getStepLength());
|
||||
builder.setTemperature(getTemperature());
|
||||
|
||||
final Double enhancedAltitude = getEnhancedAltitude();
|
||||
if (enhancedAltitude == null) {
|
||||
builder.setAltitude(getAltitude());
|
||||
} else {
|
||||
builder.setAltitude(enhancedAltitude);
|
||||
}
|
||||
|
||||
return activityPoint;
|
||||
final Float enhancedRespirationRate = getEnhancedRespirationRate();
|
||||
if (enhancedRespirationRate == null) {
|
||||
builder.setRespiratoryRate(getRespirationRate());
|
||||
} else {
|
||||
builder.setRespiratoryRate(enhancedRespirationRate);
|
||||
}
|
||||
|
||||
final Double enhancedSpeed = getEnhancedSpeed();
|
||||
if (enhancedSpeed == null) {
|
||||
builder.setSpeed(getSpeed());
|
||||
} else {
|
||||
builder.setSpeed(enhancedSpeed.floatValue());
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
+10
-19
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2023-2025 José Rebelo, Thomas Kuehne
|
||||
/* Copyright (C) 2023-2026 José Rebelo, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@@ -124,24 +124,15 @@ public class GpxTrackPoint extends GPSCoordinate {
|
||||
}
|
||||
|
||||
public ActivityPoint toActivityPoint() {
|
||||
final ActivityPoint activityPoint = new ActivityPoint();
|
||||
activityPoint.setTime(time);
|
||||
activityPoint.setLocation(this);
|
||||
activityPoint.setHeartRate(heartRate);
|
||||
if (!Float.isNaN(speed)) {
|
||||
activityPoint.setSpeed(speed);
|
||||
}
|
||||
activityPoint.setCadence(cadence);
|
||||
if (!Double.isNaN(depth)) {
|
||||
activityPoint.setDepth(depth);
|
||||
}
|
||||
if (!Double.isNaN(temperature)) {
|
||||
activityPoint.setTemperature(temperature);
|
||||
}
|
||||
if (description != null && description.length() > 0) {
|
||||
activityPoint.setDescription(description);
|
||||
}
|
||||
final ActivityPoint.Builder builder = new ActivityPoint.Builder(time);
|
||||
builder.setLocation(this);
|
||||
builder.setHeartRate(heartRate);
|
||||
builder.setSpeed(speed);
|
||||
builder.setCadence(cadence);
|
||||
builder.setDepth(depth);
|
||||
builder.setTemperature(temperature);
|
||||
builder.setDescription(description);
|
||||
|
||||
return activityPoint;
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user