mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-26 16:41:43 +01:00
Garmin: Parse some swimming stats
This commit is contained in:
parent
b4dc1d2358
commit
bcc6c23097
@ -28,6 +28,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitFile;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.enums.GarminSport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitLap;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitPhysiologicalMetrics;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitRecord;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitSession;
|
||||
@ -47,6 +48,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
private FitSport sport = null;
|
||||
private FitPhysiologicalMetrics physiologicalMetrics = null;
|
||||
private final List<FitSet> sets = new ArrayList<>();
|
||||
private final List<FitLap> laps = new ArrayList<>();
|
||||
|
||||
public GarminWorkoutParser(final Context context) {
|
||||
this.context = context;
|
||||
@ -102,6 +104,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
sport = null;
|
||||
physiologicalMetrics = null;
|
||||
sets.clear();
|
||||
laps.clear();
|
||||
}
|
||||
|
||||
public boolean handleRecord(final RecordData record) {
|
||||
@ -132,6 +135,9 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
} else if (record instanceof FitSet) {
|
||||
LOG.trace("Set: {}", record);
|
||||
sets.add((FitSet) record);
|
||||
} else if (record instanceof FitLap) {
|
||||
LOG.trace("Lap: {}", record);
|
||||
laps.add((FitLap) record);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -166,6 +172,12 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
if (session.getTotalDistance() != null) {
|
||||
summaryData.add(DISTANCE_METERS, session.getTotalDistance() / 100f, UNIT_METERS);
|
||||
}
|
||||
if (session.getPoolLength() != null) {
|
||||
summaryData.add(POOL_LENGTH, session.getPoolLength(), UNIT_METERS);
|
||||
}
|
||||
if (session.getAvgSwolf() != null) {
|
||||
summaryData.add(SWOLF_AVG, session.getAvgSwolf(), UNIT_NONE);
|
||||
}
|
||||
if (session.getTotalSteps() != null) {
|
||||
summaryData.add(STEPS, session.getTotalSteps(), UNIT_STEPS);
|
||||
}
|
||||
@ -214,6 +226,9 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
if (session.getTotalDescent() != null) {
|
||||
summaryData.add(DESCENT_DISTANCE, session.getTotalDescent(), UNIT_METERS);
|
||||
}
|
||||
if (session.getAvgSwimCadence() != null) {
|
||||
summaryData.add(SWIM_AVG_CADENCE, session.getAvgSwimCadence(), UNIT_STROKES_PER_LENGTH);
|
||||
}
|
||||
|
||||
if (session.getEnhancedAvgSpeed() != null) {
|
||||
if (ActivityKind.isPaceActivity(activityKind)) {
|
||||
@ -343,6 +358,10 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
|
||||
}
|
||||
}
|
||||
|
||||
if (!laps.isEmpty()) {
|
||||
final boolean anySwolf = laps.stream().anyMatch(l -> l.getAvgSwolf() != null);
|
||||
}
|
||||
|
||||
summaryData.add(
|
||||
INTERNAL_HAS_GPS,
|
||||
String.valueOf(activityPoints.stream().anyMatch(p -> p.getLocation() != null))
|
||||
|
@ -67,6 +67,7 @@ public class ActivitySummaryEntries {
|
||||
public static final String EVERSION_ANGLE_MAX = "eversionAngleMax";
|
||||
|
||||
public static final String DISTANCE_METERS = "distanceMeters";
|
||||
public static final String POOL_LENGTH = "poolLength";
|
||||
public static final String ELEVATION_GAIN = "elevationGain";
|
||||
public static final String ELEVATION_LOSS = "elevationLoss";
|
||||
|
||||
@ -119,6 +120,7 @@ public class ActivitySummaryEntries {
|
||||
public static final String SWOLF_AVG = "swolfAvg";
|
||||
public static final String SWOLF_MAX = "swolfMax";
|
||||
public static final String SWOLF_MIN = "swolfMin";
|
||||
public static final String SWIM_AVG_CADENCE = "swim_avg_cadence";
|
||||
|
||||
public static final String CALORIES_BURNT = "caloriesBurnt";
|
||||
public static final String TRAINING_EFFECT_AEROBIC = "aerobicTrainingEffect";
|
||||
@ -159,6 +161,7 @@ public class ActivitySummaryEntries {
|
||||
public static final String UNIT_STROKES = "strokes_unit";
|
||||
public static final String UNIT_STROKES_PER_MINUTE = "strokes_minute";
|
||||
public static final String UNIT_STROKES_PER_SECOND = "strokes_second";
|
||||
public static final String UNIT_STROKES_PER_LENGTH = "strokes_per_length";
|
||||
public static final String UNIT_JUMPS = "jumps_unit";
|
||||
public static final String UNIT_JUMPS_PER_MINUTE = "jumps_minute";
|
||||
public static final String UNIT_YARD = "yard";
|
||||
|
@ -190,6 +190,7 @@ public class ActivitySummaryJsonSummary {
|
||||
JUMPS, JUMP_RATE_AVG, JUMP_RATE_MAX
|
||||
));
|
||||
put(GROUP_SWIMMING, Arrays.asList(
|
||||
POOL_LENGTH, SWIM_AVG_CADENCE,
|
||||
SWOLF_INDEX, SWOLF_AVG, SWOLF_MAX, SWOLF_MIN, SWIM_STYLE
|
||||
));
|
||||
put(GROUP_TRAINING_EFFECT, Arrays.asList(
|
||||
|
@ -10,6 +10,7 @@ import java.util.Map;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType;
|
||||
|
||||
/** @noinspection ArraysAsListWithZeroOrOneArgument*/
|
||||
public class GlobalFITMessage {
|
||||
public static GlobalFITMessage FILE_ID = new GlobalFITMessage(0, "FILE_ID", Arrays.asList(
|
||||
new FieldDefinitionPrimitive(0, BaseType.ENUM, "type", FieldDefinitionFactory.FIELD.FILE_TYPE),
|
||||
@ -112,8 +113,13 @@ public class GlobalFITMessage {
|
||||
new FieldDefinitionPrimitive(30, BaseType.SINT32, "nec_longitude", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(31, BaseType.SINT32, "swc_latitude", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(32, BaseType.SINT32, "swc_longitude", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(33, BaseType.UINT16, "num_lengths"),
|
||||
new FieldDefinitionPrimitive(38, BaseType.SINT32, "end_latitude", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(39, BaseType.SINT32, "end_longitude", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(44, BaseType.UINT16, "pool_length", 100, 0), // m
|
||||
new FieldDefinitionPrimitive(47, BaseType.UINT16, "num_active_lengths"),
|
||||
new FieldDefinitionPrimitive(79, BaseType.UINT16, "avg_swim_cadence", 10, 0), // rpm
|
||||
new FieldDefinitionPrimitive(80, BaseType.UINT16, "avg_swolf"),
|
||||
new FieldDefinitionPrimitive(110, BaseType.STRING, 64, "sport_profile_name"),
|
||||
new FieldDefinitionPrimitive(124, BaseType.UINT32, "enhanced_avg_speed", 1000, 0), // m/s
|
||||
new FieldDefinitionPrimitive(125, BaseType.UINT32, "enhanced_max_speed", 1000, 0), // m/s
|
||||
@ -121,14 +127,19 @@ public class GlobalFITMessage {
|
||||
new FieldDefinitionPrimitive(170, BaseType.UINT16, "enhanced_max_respiration_rate", 100, 0 ), // breaths/min
|
||||
new FieldDefinitionPrimitive(178, BaseType.UINT16, "estimated_sweat_loss"), // ml
|
||||
new FieldDefinitionPrimitive(180, BaseType.UINT16, "enhanced_min_respiration_rate", 100, 0 ), // breaths/min
|
||||
new FieldDefinitionPrimitive(188, BaseType.ENUM, "primary_benefit"), // 1 recovery
|
||||
new FieldDefinitionPrimitive(194, BaseType.UINT8, "avg_spo2"),
|
||||
new FieldDefinitionPrimitive(195, BaseType.UINT8, "avg_stress"),
|
||||
new FieldDefinitionPrimitive(196, BaseType.UINT16, "resting_calories"), // kcal
|
||||
new FieldDefinitionPrimitive(197, BaseType.UINT8, "hrv_sdrr"), // ms
|
||||
new FieldDefinitionPrimitive(198, BaseType.UINT8, "hrv_rmssd"), // ms
|
||||
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
|
||||
));
|
||||
|
||||
public static GlobalFITMessage LAP = new GlobalFITMessage(19, "LAP", Arrays.asList(
|
||||
new FieldDefinitionPrimitive(0, BaseType.ENUM, "event"), // 9 lap
|
||||
new FieldDefinitionPrimitive(1, BaseType.ENUM, "event_type"), // 1 stop
|
||||
new FieldDefinitionPrimitive(2, BaseType.UINT32, "start_time"),
|
||||
new FieldDefinitionPrimitive(3, BaseType.SINT32, "start_lat", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(4, BaseType.SINT32, "start_long", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
new FieldDefinitionPrimitive(5, BaseType.SINT32, "end_lat", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||
@ -136,8 +147,24 @@ public class GlobalFITMessage {
|
||||
new FieldDefinitionPrimitive(7, BaseType.UINT32, "total_elapsed_time", 1000, 0), // s
|
||||
new FieldDefinitionPrimitive(8, BaseType.UINT32, "total_timer_time", 1000, 0), // s
|
||||
new FieldDefinitionPrimitive(9, BaseType.UINT32, "total_distance", 100, 0), // m
|
||||
new FieldDefinitionPrimitive(10, BaseType.UINT32, "total_cycles"),
|
||||
new FieldDefinitionPrimitive(11, BaseType.UINT16, "total_calores"),
|
||||
new FieldDefinitionPrimitive(15, BaseType.UINT8, "avg_heart_rate"),
|
||||
new FieldDefinitionPrimitive(16, BaseType.UINT8, "max_heart_rate"),
|
||||
new FieldDefinitionPrimitive(17, BaseType.UINT8, "avg_cadence"), // rpm
|
||||
new FieldDefinitionPrimitive(21, BaseType.UINT16, "total_ascent"), // m
|
||||
new FieldDefinitionPrimitive(22, BaseType.UINT16, "total_descent"), // m
|
||||
new FieldDefinitionPrimitive(24, BaseType.ENUM, "lap_trigger"), // 0 manual
|
||||
new FieldDefinitionPrimitive(25, BaseType.ENUM, "sport"), // 5 swimming
|
||||
new FieldDefinitionPrimitive(32, BaseType.UINT16, "num_lengths"),
|
||||
new FieldDefinitionPrimitive(35, BaseType.UINT16, "first_length_index"),
|
||||
new FieldDefinitionPrimitive(37, BaseType.UINT16, "avg_stroke_distance"),
|
||||
new FieldDefinitionPrimitive(38, BaseType.ENUM, "swim_style"), // 0 freestyle 2 breaststroke 5 mixed
|
||||
new FieldDefinitionPrimitive(39, BaseType.ENUM, "sub_sport"), // 17 = lap swimming
|
||||
new FieldDefinitionPrimitive(40, BaseType.UINT16, "num_active_lengths"),
|
||||
new FieldDefinitionPrimitive(73, BaseType.UINT16, "avg_swolf"),
|
||||
new FieldDefinitionPrimitive(110, BaseType.UINT32, "enhanced_avg_speed", 100, 0), // m/s
|
||||
new FieldDefinitionPrimitive(111, BaseType.UINT32, "enhanced_max_speed", 100, 0), // m/s
|
||||
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
|
||||
));
|
||||
|
||||
@ -193,6 +220,16 @@ public class GlobalFITMessage {
|
||||
new FieldDefinitionPrimitive(5, BaseType.STRING, 16, "name")
|
||||
));
|
||||
|
||||
public static GlobalFITMessage ACTIVITY = new GlobalFITMessage(34, "ACTIVITY", Arrays.asList(
|
||||
new FieldDefinitionPrimitive(0, BaseType.UINT32, "total_timer_time"),
|
||||
new FieldDefinitionPrimitive(1, BaseType.UINT16, "num_sessions"),
|
||||
new FieldDefinitionPrimitive(2, BaseType.ENUM, "type"), // 0
|
||||
new FieldDefinitionPrimitive(3, BaseType.ENUM, "event"), // 26 activity
|
||||
new FieldDefinitionPrimitive(4, BaseType.ENUM, "event_type"), // 1 stop
|
||||
new FieldDefinitionPrimitive(5, BaseType.UINT32, "local_timestamp"), // garmin timestamp, but in user timezone
|
||||
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
|
||||
));
|
||||
|
||||
public static GlobalFITMessage FILE_CREATOR = new GlobalFITMessage(49, "FILE_CREATOR", Arrays.asList(
|
||||
new FieldDefinitionPrimitive(0, BaseType.UINT16, "software_version"),
|
||||
new FieldDefinitionPrimitive(1, BaseType.UINT8, "hardware_version")
|
||||
@ -427,6 +464,7 @@ public class GlobalFITMessage {
|
||||
put(23, DEVICE_INFO);
|
||||
put(26, WORKOUT);
|
||||
put(31, COURSE);
|
||||
put(34, ACTIVITY);
|
||||
put(49, FILE_CREATOR);
|
||||
put(55, MONITORING);
|
||||
put(103, MONITORING_INFO);
|
||||
|
@ -0,0 +1,57 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader;
|
||||
|
||||
//
|
||||
// WARNING: This class was auto-generated, please avoid modifying it directly.
|
||||
// See nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen
|
||||
//
|
||||
public class FitActivity extends RecordData {
|
||||
public FitActivity(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
|
||||
super(recordDefinition, recordHeader);
|
||||
|
||||
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
|
||||
if (globalNumber != 34) {
|
||||
throw new IllegalArgumentException("FitActivity expects global messages of " + 34 + ", got " + globalNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTotalTimerTime() {
|
||||
return (Long) getFieldByNumber(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getNumSessions() {
|
||||
return (Integer) getFieldByNumber(1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getType() {
|
||||
return (Integer) getFieldByNumber(2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getEvent() {
|
||||
return (Integer) getFieldByNumber(3);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getEventType() {
|
||||
return (Integer) getFieldByNumber(4);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getLocalTimestamp() {
|
||||
return (Long) getFieldByNumber(5);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTimestamp() {
|
||||
return (Long) getFieldByNumber(253);
|
||||
}
|
||||
}
|
@ -20,6 +20,21 @@ public class FitLap extends RecordData {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getEvent() {
|
||||
return (Integer) getFieldByNumber(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getEventType() {
|
||||
return (Integer) getFieldByNumber(1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getStartTime() {
|
||||
return (Long) getFieldByNumber(2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Double getStartLat() {
|
||||
return (Double) getFieldByNumber(3);
|
||||
@ -55,6 +70,31 @@ public class FitLap extends RecordData {
|
||||
return (Double) getFieldByNumber(9);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTotalCycles() {
|
||||
return (Long) getFieldByNumber(10);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getTotalCalores() {
|
||||
return (Integer) getFieldByNumber(11);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getAvgHeartRate() {
|
||||
return (Integer) getFieldByNumber(15);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getMaxHeartRate() {
|
||||
return (Integer) getFieldByNumber(16);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getAvgCadence() {
|
||||
return (Integer) getFieldByNumber(17);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getTotalAscent() {
|
||||
return (Integer) getFieldByNumber(21);
|
||||
@ -65,6 +105,61 @@ public class FitLap extends RecordData {
|
||||
return (Integer) getFieldByNumber(22);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getLapTrigger() {
|
||||
return (Integer) getFieldByNumber(24);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getSport() {
|
||||
return (Integer) getFieldByNumber(25);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getNumLengths() {
|
||||
return (Integer) getFieldByNumber(32);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getFirstLengthIndex() {
|
||||
return (Integer) getFieldByNumber(35);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getAvgStrokeDistance() {
|
||||
return (Integer) getFieldByNumber(37);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getSwimStyle() {
|
||||
return (Integer) getFieldByNumber(38);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getSubSport() {
|
||||
return (Integer) getFieldByNumber(39);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getNumActiveLengths() {
|
||||
return (Integer) getFieldByNumber(40);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getAvgSwolf() {
|
||||
return (Integer) getFieldByNumber(73);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Double getEnhancedAvgSpeed() {
|
||||
return (Double) getFieldByNumber(110);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Double getEnhancedMaxSpeed() {
|
||||
return (Double) getFieldByNumber(111);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTimestamp() {
|
||||
return (Long) getFieldByNumber(253);
|
||||
|
@ -41,6 +41,8 @@ public class FitRecordDataFactory {
|
||||
return new FitWorkout(recordDefinition, recordHeader);
|
||||
case 31:
|
||||
return new FitCourse(recordDefinition, recordHeader);
|
||||
case 34:
|
||||
return new FitActivity(recordDefinition, recordHeader);
|
||||
case 49:
|
||||
return new FitFileCreator(recordDefinition, recordHeader);
|
||||
case 55:
|
||||
|
@ -140,6 +140,11 @@ public class FitSession extends RecordData {
|
||||
return (Double) getFieldByNumber(32);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getNumLengths() {
|
||||
return (Integer) getFieldByNumber(33);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Double getEndLatitude() {
|
||||
return (Double) getFieldByNumber(38);
|
||||
@ -150,6 +155,26 @@ public class FitSession extends RecordData {
|
||||
return (Double) getFieldByNumber(39);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Float getPoolLength() {
|
||||
return (Float) getFieldByNumber(44);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getNumActiveLengths() {
|
||||
return (Integer) getFieldByNumber(47);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Float getAvgSwimCadence() {
|
||||
return (Float) getFieldByNumber(79);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getAvgSwolf() {
|
||||
return (Integer) getFieldByNumber(80);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getSportProfileName() {
|
||||
return (String) getFieldByNumber(110);
|
||||
@ -185,6 +210,11 @@ public class FitSession extends RecordData {
|
||||
return (Float) getFieldByNumber(180);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getPrimaryBenefit() {
|
||||
return (Integer) getFieldByNumber(188);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getAvgSpo2() {
|
||||
return (Integer) getFieldByNumber(194);
|
||||
@ -195,6 +225,11 @@ public class FitSession extends RecordData {
|
||||
return (Integer) getFieldByNumber(195);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getRestingCalories() {
|
||||
return (Integer) getFieldByNumber(196);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getHrvSdrr() {
|
||||
return (Integer) getFieldByNumber(197);
|
||||
|
@ -2208,6 +2208,9 @@
|
||||
<string name="sonyswr12_settings_alarm_interval_summary">Smart alarm interval is interval before of installed alarm. In this interval device is trying to detect lightest phase of sleep to awake user</string>
|
||||
<!-- activity summary labels-->
|
||||
<string name="distanceMeters">Distance</string>
|
||||
<string name="poolLength">Pool length</string>
|
||||
<string name="swim_avg_cadence">Avg Swim Cadence</string>
|
||||
<string name="strokes_per_length">strokes/length</string>
|
||||
<string name="ascentMeters">Uphill</string>
|
||||
<string name="descentMeters">Downhill</string>
|
||||
<string name="ascentDistance">Uphill distance</string>
|
||||
|
Loading…
Reference in New Issue
Block a user