mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Garmin: extend FIT file parsing 12 - LOCATION 29 / symbol 3
This commit is contained in:
committed by
José Rebelo
parent
d9cfcc025e
commit
36f5c8a31e
+3
@@ -15,6 +15,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefi
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrZoneHighBoundary;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrZoneHighBoundary;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrvStatus;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrvStatus;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLanguage;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLanguage;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLocationSymbol;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem;
|
||||||
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.fieldDefinitions.FieldDefinitionSwimStyle;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionSwimStyle;
|
||||||
@@ -50,6 +51,7 @@ public class FieldDefinitionFactory {
|
|||||||
case WEATHER_AQI -> new FieldDefinitionWeatherAqi(localNumber, size, baseType, name);
|
case WEATHER_AQI -> new FieldDefinitionWeatherAqi(localNumber, size, baseType, name);
|
||||||
case COORDINATE -> new FieldDefinitionCoordinate(localNumber, size, baseType, name);
|
case COORDINATE -> new FieldDefinitionCoordinate(localNumber, size, baseType, name);
|
||||||
case SWIM_STYLE -> new FieldDefinitionSwimStyle(localNumber, size, baseType, name);
|
case SWIM_STYLE -> new FieldDefinitionSwimStyle(localNumber, size, baseType, name);
|
||||||
|
case LOCATION_SYMBOL -> new FieldDefinitionLocationSymbol(localNumber, size, baseType, name, scale, offset);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,5 +77,6 @@ public class FieldDefinitionFactory {
|
|||||||
WEATHER_AQI,
|
WEATHER_AQI,
|
||||||
COORDINATE,
|
COORDINATE,
|
||||||
SWIM_STYLE,
|
SWIM_STYLE,
|
||||||
|
LOCATION_SYMBOL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -699,7 +699,7 @@ public class GlobalFITMessage {
|
|||||||
new FieldDefinitionPrimitive(0, BaseType.STRING, 32, "name"),
|
new FieldDefinitionPrimitive(0, BaseType.STRING, 32, "name"),
|
||||||
new FieldDefinitionPrimitive(1, BaseType.SINT32, "position_lat", FieldDefinitionFactory.FIELD.COORDINATE),
|
new FieldDefinitionPrimitive(1, BaseType.SINT32, "position_lat", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||||
new FieldDefinitionPrimitive(2, BaseType.SINT32, "position_long", FieldDefinitionFactory.FIELD.COORDINATE),
|
new FieldDefinitionPrimitive(2, BaseType.SINT32, "position_long", FieldDefinitionFactory.FIELD.COORDINATE),
|
||||||
new FieldDefinitionPrimitive(3, BaseType.UINT16, "symbol"),
|
new FieldDefinitionPrimitive(3, BaseType.UINT16, "symbol", FieldDefinitionFactory.FIELD.LOCATION_SYMBOL),
|
||||||
new FieldDefinitionPrimitive(4, BaseType.UINT16, "altitude", 5, 500), // m
|
new FieldDefinitionPrimitive(4, BaseType.UINT16, "altitude", 5, 500), // m
|
||||||
new FieldDefinitionPrimitive(5, BaseType.UINT16, "enhanced_altitude"),
|
new FieldDefinitionPrimitive(5, BaseType.UINT16, "enhanced_altitude"),
|
||||||
new FieldDefinitionPrimitive(6, BaseType.STRING, "description"),
|
new FieldDefinitionPrimitive(6, BaseType.STRING, "description"),
|
||||||
|
|||||||
+2
@@ -34,6 +34,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefi
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionGoalType;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionGoalType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrvStatus;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrvStatus;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLanguage;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLanguage;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLocationSymbol;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem;
|
||||||
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.fieldDefinitions.FieldDefinitionSwimStyle;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionSwimStyle;
|
||||||
@@ -363,6 +364,7 @@ public class FitCodeGen {
|
|||||||
case WEATHER_AQI -> FieldDefinitionWeatherAqi.AQI_LEVELS.class;
|
case WEATHER_AQI -> FieldDefinitionWeatherAqi.AQI_LEVELS.class;
|
||||||
case COORDINATE -> Double.class;
|
case COORDINATE -> Double.class;
|
||||||
case SWIM_STYLE -> FieldDefinitionSwimStyle.SwimStyle.class;
|
case SWIM_STYLE -> FieldDefinitionSwimStyle.SwimStyle.class;
|
||||||
|
case LOCATION_SYMBOL -> FieldDefinitionLocationSymbol.LocationSymbol.class;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+236
@@ -0,0 +1,236 @@
|
|||||||
|
/* Copyright (C) 2025 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.service.devices.garmin.fit.fieldDefinitions;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FieldDefinition;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType;
|
||||||
|
|
||||||
|
public class FieldDefinitionLocationSymbol extends FieldDefinition {
|
||||||
|
|
||||||
|
public FieldDefinitionLocationSymbol(int localNumber, int size, BaseType baseType, String name, int scale, int offset) {
|
||||||
|
super(localNumber, size, baseType, name, scale, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object decode(ByteBuffer byteBuffer) {
|
||||||
|
final Object rawObj = baseType.decode(byteBuffer, scale, offset);
|
||||||
|
if (rawObj != null) {
|
||||||
|
final Number raw = (Number) rawObj;
|
||||||
|
return LocationSymbol.fromId(raw.intValue());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuffer byteBuffer, Object o) {
|
||||||
|
if (o instanceof LocationSymbol locationSymbol) {
|
||||||
|
baseType.encode(byteBuffer, locationSymbol.getId(), scale, offset);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
baseType.encode(byteBuffer, o, scale, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LocationSymbol {
|
||||||
|
Airport(0, "Airport"),
|
||||||
|
Amusement_Park(1, "Amusement Park"),
|
||||||
|
Anchor(2, "Anchor"),
|
||||||
|
Ball_Park(3, "Ball Park"),
|
||||||
|
Bank(4, "Bank"),
|
||||||
|
Bar(5, "Bar"),
|
||||||
|
Block_Blue(6, "Block, Blue"),
|
||||||
|
Boat_Ramp(7, "Boat Ramp"),
|
||||||
|
Bowling(8, "Bowling"),
|
||||||
|
Bridge(9, "Bridge"),
|
||||||
|
Building(10, "Building"),
|
||||||
|
Campground(11, "Campground"),
|
||||||
|
Car(12, "Car"),
|
||||||
|
Car_Rental(13, "Car Rental"),
|
||||||
|
Car_Repair(14, "Car Repair"),
|
||||||
|
Cemetery(15, "Cemetery"),
|
||||||
|
Church(16, "Church"),
|
||||||
|
City_Large(17, "City (Large)"),
|
||||||
|
City_Medium(18, "City (Medium)"),
|
||||||
|
City_Small(19, "City (Small)"),
|
||||||
|
Civil(20, "Civil"),
|
||||||
|
Controlled_Area(21, "Controlled Area"),
|
||||||
|
Convenience_Store(22, "Convenience Store"),
|
||||||
|
Crossing(23, "Crossing"),
|
||||||
|
Dam(24, "Dam"),
|
||||||
|
Skull_and_Crossbones(25, "Skull and Crossbones"),
|
||||||
|
Danger_Area(26, "Danger Area"),
|
||||||
|
Department_Store(27, "Department Store"),
|
||||||
|
Diver_Down_Flag_1(28, "Diver Down Flag 1"),
|
||||||
|
Diver_Down_Flag_2(29, "Diver Down Flag 2"),
|
||||||
|
Drinking_Water(30, "Drinking Water"),
|
||||||
|
Unknown_31(31, "Unknown 31"),
|
||||||
|
Fast_Food(32, "Fast Food"),
|
||||||
|
Fishing_Area(33, "Fishing Area"),
|
||||||
|
Fitness_Center(34, "Fitness Center"),
|
||||||
|
Forest(35, "Forest"),
|
||||||
|
Gas_Station(36, "Gas Station"),
|
||||||
|
Glider_Area(37, "Glider Area"),
|
||||||
|
Golf_Course(38, "Golf Course"),
|
||||||
|
Lodging(39, "Lodging"),
|
||||||
|
Hunting_Area(40, "Hunting Area"),
|
||||||
|
Information(41, "Information"),
|
||||||
|
Live_Theater(42, "Live Theater"),
|
||||||
|
Light(43, "Light"),
|
||||||
|
Man_Overboard(44, "Man Overboard"),
|
||||||
|
Medical_Facility(45, "Medical Facility"),
|
||||||
|
Mine(46, "Mine"),
|
||||||
|
Movie_Theater(47, "Movie Theater"),
|
||||||
|
Museum(48, "Museum"),
|
||||||
|
Oil_Field(49, "Oil Field"),
|
||||||
|
Parachute_Area(50, "Parachute Area"),
|
||||||
|
Park(51, "Park"),
|
||||||
|
Parking_Area(52, "Parking Area"),
|
||||||
|
Pharmacy(53, "Pharmacy"),
|
||||||
|
Picnic_Area(54, "Picnic Area"),
|
||||||
|
Pizza(55, "Pizza"),
|
||||||
|
Post_Office(56, "Post Office"),
|
||||||
|
RV_Park(57, "RV Park"),
|
||||||
|
Residence(58, "Residence"),
|
||||||
|
Restricted_Area(59, "Restricted Area"),
|
||||||
|
Restaurant(60, "Restaurant"),
|
||||||
|
Restroom(61, "Restroom"),
|
||||||
|
Scales(62, "Scales"),
|
||||||
|
Scenic_Area(63, "Scenic Area"),
|
||||||
|
School(64, "School"),
|
||||||
|
Shipwreck(65, "Shipwreck"),
|
||||||
|
Shopping_Center(66, "Shopping Center"),
|
||||||
|
Short_Tower(67, "Short Tower"),
|
||||||
|
Shower(68, "Shower"),
|
||||||
|
Skiing_Area(69, "Skiing Area"),
|
||||||
|
Stadium(70, "Stadium"),
|
||||||
|
Summit(71, "Summit"),
|
||||||
|
Swimming_Area(72, "Swimming Area"),
|
||||||
|
Tall_Tower(73, "Tall Tower"),
|
||||||
|
Telephone(74, "Telephone"),
|
||||||
|
Toll_Booth(75, "Toll Booth"),
|
||||||
|
Trail_Head(76, "Trail Head"),
|
||||||
|
Truck_Stop(77, "Truck Stop"),
|
||||||
|
Tunnel(78, "Tunnel"),
|
||||||
|
Ultralight_Area(79, "Ultralight Area"),
|
||||||
|
Zoo(80, "Zoo"),
|
||||||
|
Geocache(81, "Geocache"),
|
||||||
|
Geocache_Found(82, "Geocache Found"),
|
||||||
|
Flag_Blue(83, "Flag, Blue"),
|
||||||
|
Pin_Blue(84, "Pin, Blue"),
|
||||||
|
Bike_Trail(85, "Bike Trail"),
|
||||||
|
Ice_Skating(86, "Ice Skating"),
|
||||||
|
Unknown_87(87, "Unknown 87"),
|
||||||
|
Beacon(88, "Beacon"),
|
||||||
|
Horn(89, "Horn"),
|
||||||
|
Beach(90, "Beach"),
|
||||||
|
Buoy_White(91, "Buoy, White"),
|
||||||
|
Wrecker(92, "Wrecker"),
|
||||||
|
Navaid_Amber(93, "Navaid, Amber"),
|
||||||
|
Navaid_Black(94, "Navaid, Black"),
|
||||||
|
Navaid_Blue(95, "Navaid, Blue"),
|
||||||
|
Navaid_GreenWhite(96, "Navaid, Green/White"),
|
||||||
|
Navaid_Green(97, "Navaid, Green"),
|
||||||
|
Navaid_GreenRed(98, "Navaid, Green/Red"),
|
||||||
|
Navaid_Orange(99, "Navaid, Orange"),
|
||||||
|
Navaid_RedGreen(100, "Navaid, Red/Green"),
|
||||||
|
Navaid_RedWhite(101, "Navaid, Red/White"),
|
||||||
|
Navaid_Red(102, "Navaid, Red"),
|
||||||
|
Navaid_Violet(103, "Navaid, Violet"),
|
||||||
|
Navaid_White(104, "Navaid, White"),
|
||||||
|
Navaid_WhiteGreen(105, "Navaid, White/Green"),
|
||||||
|
Navaid_WhiteRed(106, "Navaid, White/Red"),
|
||||||
|
Unknown_107(107, "Unknown 107"),
|
||||||
|
Bell(108, "Bell"),
|
||||||
|
Block_Green(109, "Block, Green"),
|
||||||
|
Block_Red(110, "Block, Red"),
|
||||||
|
Food_Source(111, "Food Source"),
|
||||||
|
Unknown_112(112, "Unknown 112"),
|
||||||
|
Unknown_113(113, "Unknown 113"),
|
||||||
|
Unknown_114(114, "Unknown 114"),
|
||||||
|
Unknown_115(115, "Unknown 115"),
|
||||||
|
Flag_Green(116, "Flag, Green"),
|
||||||
|
Flag_Red(117, "Flag, Red"),
|
||||||
|
Pin_Green(118, "Pin, Green"),
|
||||||
|
Pin_Red(119, "Pin, Red"),
|
||||||
|
ATV(120, "ATV"),
|
||||||
|
Big_Game(121, "Big Game"),
|
||||||
|
Blind(122, "Blind"),
|
||||||
|
Blood_Trail(123, "Blood Trail"),
|
||||||
|
Cover(124, "Cover"),
|
||||||
|
Covey(125, "Covey"),
|
||||||
|
Unknown_126(126, "Unknown 126"),
|
||||||
|
Furbearer(127, "Furbearer"),
|
||||||
|
Lodge(128, "Lodge"),
|
||||||
|
Small_Game(129, "Small Game"),
|
||||||
|
Animal_Tracks(130, "Animal Tracks"),
|
||||||
|
Treed_Quarry(131, "Treed Quarry"),
|
||||||
|
Tree_Stand(132, "Tree Stand"),
|
||||||
|
Truck(133, "Truck"),
|
||||||
|
Upland_Game(134, "Upland Game"),
|
||||||
|
Waterfowl(135, "Waterfowl"),
|
||||||
|
Water_Source(136, "Water Source"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String gxpSymbol;
|
||||||
|
|
||||||
|
LocationSymbol(int i, String symbol) {
|
||||||
|
id = i;
|
||||||
|
gxpSymbol = symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static LocationSymbol fromId(int id) {
|
||||||
|
for (LocationSymbol symbol : values()) {
|
||||||
|
if (id == symbol.id) {
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static LocationSymbol fromGxpSymbol(String sym) {
|
||||||
|
if (sym == null || sym.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (LocationSymbol symbol : values()) {
|
||||||
|
if (symbol.gxpSymbol.equals(sym)) {
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Garmin Basecamp uses the blue flag for unknown symbols
|
||||||
|
return Flag_Blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGxpSymbol() {
|
||||||
|
return gxpSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return gxpSymbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-3
@@ -22,6 +22,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecord
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData;
|
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.RecordDefinition;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionLocationSymbol.LocationSymbol;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING: This class was auto-generated, please avoid modifying it directly.
|
* WARNING: This class was auto-generated, please avoid modifying it directly.
|
||||||
@@ -55,8 +56,8 @@ public class FitLocation extends RecordData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Integer getSymbol() {
|
public LocationSymbol getSymbol() {
|
||||||
return (Integer) getFieldByNumber(3);
|
return (LocationSymbol) getFieldByNumber(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -107,7 +108,7 @@ public class FitLocation extends RecordData {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setSymbol(final Integer value) {
|
public Builder setSymbol(final LocationSymbol value) {
|
||||||
setFieldByNumber(3, value);
|
setFieldByNumber(3, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user