mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-04 09:17:29 +01:00
Garmin: Map all supported workout types
This commit is contained in:
parent
8be679d1fd
commit
553f6171e6
@ -49,6 +49,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminTimeUtils;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.GarminTimeUtils;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.enums.GarminSport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionSleepStage;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionSleepStage;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitEvent;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitFileId;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitFileId;
|
||||||
@ -61,6 +62,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitStressLevel;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitStressLevel;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitTimeInZone;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitTimeInZone;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.Optional;
|
||||||
|
|
||||||
public class FitImporter {
|
public class FitImporter {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FitImporter.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FitImporter.class);
|
||||||
@ -301,29 +303,51 @@ public class FitImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getActivityKind(final Integer sport, final Integer subsport) {
|
private int getActivityKind(final Integer sport, final Integer subsport) {
|
||||||
// TODO map all sports
|
final Optional<GarminSport> garminSport = GarminSport.fromCodes(sport, subsport);
|
||||||
if (sport != null) {
|
if (garminSport.isEmpty()) {
|
||||||
switch (sport) {
|
LOG.warn("Unknown garmin sport {}/{}", sport, subsport);
|
||||||
case 2:
|
return ActivityKind.TYPE_UNKNOWN;
|
||||||
return ActivityKind.TYPE_CYCLING;
|
}
|
||||||
case 4: // fitness_equipment
|
|
||||||
case 10: // training
|
switch (garminSport.get()) {
|
||||||
if (subsport != null) {
|
case RUN:
|
||||||
switch (subsport) {
|
case PUSH_RUN_SPEED:
|
||||||
case 15:
|
case INDOOR_PUSH_RUN_SPEED:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
case INDOOR_TRACK:
|
||||||
case 20:
|
return ActivityKind.TYPE_RUNNING;
|
||||||
return ActivityKind.TYPE_STRENGTH_TRAINING;
|
case TREADMILL:
|
||||||
default:
|
return ActivityKind.TYPE_TREADMILL;
|
||||||
LOG.warn("Unknown sub sport {} for {}", subsport, sport);
|
case E_BIKE:
|
||||||
}
|
case BIKE:
|
||||||
break;
|
return ActivityKind.TYPE_CYCLING;
|
||||||
}
|
case BIKE_INDOOR:
|
||||||
case 11:
|
return ActivityKind.TYPE_INDOOR_CYCLING;
|
||||||
return ActivityKind.TYPE_WALKING;
|
case ELLIPTICAL:
|
||||||
default:
|
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
||||||
LOG.warn("Unknown sport {}", sport);
|
case STAIR_STEPPER:
|
||||||
}
|
case PILATES:
|
||||||
|
case CARDIO:
|
||||||
|
return ActivityKind.TYPE_EXERCISE;
|
||||||
|
case POOL_SWIM:
|
||||||
|
return ActivityKind.TYPE_SWIMMING;
|
||||||
|
case OPEN_WATER:
|
||||||
|
return ActivityKind.TYPE_SWIMMING_OPENWATER;
|
||||||
|
case SOCCER:
|
||||||
|
return ActivityKind.TYPE_SOCCER;
|
||||||
|
case STRENGTH:
|
||||||
|
return ActivityKind.TYPE_STRENGTH_TRAINING;
|
||||||
|
case YOGA:
|
||||||
|
return ActivityKind.TYPE_YOGA;
|
||||||
|
case WALK:
|
||||||
|
case WALK_INDOOR:
|
||||||
|
case PUSH_WALK_SPEED:
|
||||||
|
case INDOOR_PUSH_WALK_SPEED:
|
||||||
|
return ActivityKind.TYPE_WALKING;
|
||||||
|
case HIKE:
|
||||||
|
return ActivityKind.TYPE_HIKING;
|
||||||
|
case CLIMB_INDOOR:
|
||||||
|
case BOULDERING:
|
||||||
|
return ActivityKind.TYPE_CLIMBING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.TYPE_UNKNOWN;
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.enums;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.Optional;
|
||||||
|
|
||||||
|
// Taken from CHANGELOG.fit of a Venu 3
|
||||||
|
public enum GarminSport {
|
||||||
|
NAVIGATE(0, 50),
|
||||||
|
RUN(1, 0),
|
||||||
|
TREADMILL(1, 1),
|
||||||
|
INDOOR_TRACK(1, 45),
|
||||||
|
BIKE(2, 0),
|
||||||
|
BIKE_INDOOR(2, 6),
|
||||||
|
HANDCYCLING(2, 12),
|
||||||
|
E_BIKE(2, 28),
|
||||||
|
HANDCYCLING_INDOOR(2, 88),
|
||||||
|
ELLIPTICAL(4, 15),
|
||||||
|
STAIR_STEPPER(4, 16),
|
||||||
|
PILATES(4, 44),
|
||||||
|
POOL_SWIM(5, 17),
|
||||||
|
OPEN_WATER(5, 18),
|
||||||
|
SOCCER(7, 0),
|
||||||
|
TENNIS(8, 0),
|
||||||
|
PLATFORM_TENNIS(8, 93),
|
||||||
|
TABLE_TENNIS(8, 97),
|
||||||
|
STRENGTH(10, 20),
|
||||||
|
CARDIO(10, 26),
|
||||||
|
YOGA(10, 43),
|
||||||
|
BREATHWORK(10, 62),
|
||||||
|
WALK(11, 0),
|
||||||
|
WALK_INDOOR(11, 27),
|
||||||
|
XC_CLASSIC_SKI(12, 0),
|
||||||
|
SKI(13, 0),
|
||||||
|
SNOWBOARD(14, 0),
|
||||||
|
HIKE(17, 0),
|
||||||
|
CLIMB_INDOOR(31, 68),
|
||||||
|
BOULDERING(31, 69),
|
||||||
|
SNOWSHOE(35, 0),
|
||||||
|
STAND_UP_PADDLEBOARDING(37, 0),
|
||||||
|
SOFTBALL(50, 0),
|
||||||
|
HEALTH_SNAPSHOT(60, 0),
|
||||||
|
HIIT(62, 0),
|
||||||
|
PICKLEBALL(64, 84),
|
||||||
|
PADEL(64, 85),
|
||||||
|
SQUASH(64, 94),
|
||||||
|
RACQUETBALL(64, 96),
|
||||||
|
PUSH_WALK_SPEED(65, 0),
|
||||||
|
INDOOR_PUSH_WALK_SPEED(65, 86),
|
||||||
|
PUSH_RUN_SPEED(66, 0),
|
||||||
|
INDOOR_PUSH_RUN_SPEED(66, 87),
|
||||||
|
DISC_GOLF(69, 0),
|
||||||
|
ULTIMATE_DISC(69, 92),
|
||||||
|
RUGBY(72, 0),
|
||||||
|
LACROSSE(74, 0),
|
||||||
|
VOLLEYBALL(75, 0),
|
||||||
|
MIXED_MARTIAL_ARTS(80, 0), // aka MMA
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int type;
|
||||||
|
private final int subtype;
|
||||||
|
|
||||||
|
GarminSport(final int type, final int subtype) {
|
||||||
|
this.type = type;
|
||||||
|
this.subtype = subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSubtype() {
|
||||||
|
return subtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<GarminSport> fromCodes(final int type, final int subtype) {
|
||||||
|
for (final GarminSport value : GarminSport.values()) {
|
||||||
|
if (value.getType() == type && value.getSubtype() == subtype) {
|
||||||
|
return Optional.of(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,10 @@ public final class Optional<T> {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return value == null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPresent() {
|
public boolean isPresent() {
|
||||||
return value != null;
|
return value != null;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.enums;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.test.TestBase;
|
||||||
|
|
||||||
|
public class GarminSportTest extends TestBase {
|
||||||
|
@Test
|
||||||
|
public void testNoDuplicates() {
|
||||||
|
// Ensure there are no duplicated sports with the same type and subtype
|
||||||
|
final Set<GarminSport> duplicates = new HashSet<>();
|
||||||
|
final Set<Pair<Integer, Integer>> seen = new HashSet<>();
|
||||||
|
|
||||||
|
for (final GarminSport sport : GarminSport.values()) {
|
||||||
|
final Pair<Integer, Integer> codePair = Pair.create(sport.getType(), sport.getSubtype());
|
||||||
|
if (seen.contains(codePair)) {
|
||||||
|
duplicates.add(sport);
|
||||||
|
}
|
||||||
|
seen.add(codePair);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue("Duplicated sport codes: " + duplicates, duplicates.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user