Garmin: Add global fit messages for SpO2 and respiration rate

This commit is contained in:
José Rebelo 2024-04-29 21:49:43 +01:00
parent edea80c949
commit 4205426e4b
23 changed files with 141 additions and 41 deletions

View File

@ -21,6 +21,7 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(6, BaseType.UINT16, "manufacturer_partner"),
new FieldDefinitionPrimitive(8, BaseType.STRING, 20, "product_name")
));
public static GlobalFITMessage DEVICE_SETTINGS = new GlobalFITMessage(2, "DEVICE_SETTINGS", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.UINT8, "active_time_zone"),
new FieldDefinitionPrimitive(1, BaseType.UINT32, "utc_offset"),
@ -39,6 +40,7 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(86, BaseType.ENUM, "ble_auto_upload_enabled"),
new FieldDefinitionPrimitive(90, BaseType.UINT32, "auto_activity_detect")
));
public static GlobalFITMessage USER_PROFILE = new GlobalFITMessage(3, "USER_PROFILE", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.STRING, 8, "friendly_name"),
new FieldDefinitionPrimitive(1, BaseType.ENUM, "gender"),
@ -64,6 +66,7 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(31, BaseType.UINT16, "user_running_step_length"),
new FieldDefinitionPrimitive(32, BaseType.UINT16, "user_walking_step_length")
));
public static GlobalFITMessage ZONES_TARGET = new GlobalFITMessage(7, "ZONES_TARGET", Arrays.asList(
new FieldDefinitionPrimitive(3, BaseType.UINT16, "functional_threshold_power"),
new FieldDefinitionPrimitive(1, BaseType.UINT8, "max_heart_rate"),
@ -71,6 +74,7 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(5, BaseType.ENUM, "hr_calc_type"), //1=percent_max_hr
new FieldDefinitionPrimitive(7, BaseType.ENUM, "pwr_calc_type") //1=percent_ftp
));
public static GlobalFITMessage SPORT = new GlobalFITMessage(12, "SPORT", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.ENUM, "sport"),
new FieldDefinitionPrimitive(1, BaseType.ENUM, "sub_sport"),
@ -87,6 +91,7 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(3, BaseType.UINT8, "heart_rate"),
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
));
public static GlobalFITMessage DEVICE_INFO = new GlobalFITMessage(23, "DEVICE_INFO", Arrays.asList(
new FieldDefinitionPrimitive(2, BaseType.UINT16, "manufacturer"),
new FieldDefinitionPrimitive(3, BaseType.UINT32Z, "serial_number"),
@ -94,10 +99,12 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(5, BaseType.UINT16, "software_version"),
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")
));
public static GlobalFITMessage MONITORING = new GlobalFITMessage(55, "MONITORING", Arrays.asList(
new FieldDefinitionPrimitive(2, BaseType.UINT32, "distance"),
new FieldDefinitionPrimitive(3, BaseType.UINT32, "cycles"),
@ -143,6 +150,7 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(17, BaseType.ENUM, "air_quality"),
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
));
public static GlobalFITMessage WATCHFACE_SETTINGS = new GlobalFITMessage(159, "WATCHFACE_SETTINGS", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.ENUM, "mode"), //1=analog
new FieldDefinitionPrimitive(1, BaseType.BASE_TYPE_BYTE, "layout")
@ -155,23 +163,38 @@ public class GlobalFITMessage {
new FieldDefinitionPrimitive(3, BaseType.STRING, 64, "field_name"),
new FieldDefinitionPrimitive(8, BaseType.STRING, 16, "units")
));
public static GlobalFITMessage DEVELOPER_DATA = new GlobalFITMessage(207, "DEVELOPER_DATA", Arrays.asList(
new FieldDefinitionPrimitive(1, BaseType.BASE_TYPE_BYTE, 16, "application_id"),
new FieldDefinitionPrimitive(3, BaseType.UINT8, "developer_data_index")
));
// UNK_216(216, null), //activity
public static GlobalFITMessage ALARM_SETTINGS = new GlobalFITMessage(222, "ALARM_SETTINGS", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.UINT16, "time", FieldDefinitionFactory.FIELD.ALARM)
));
public static GlobalFITMessage STRESS_LEVEL = new GlobalFITMessage(227, "STRESS_LEVEL", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.SINT16, "stress_level_value"),
new FieldDefinitionPrimitive(1, BaseType.UINT32, "stress_level_time", FieldDefinitionFactory.FIELD.TIMESTAMP)
));
public static GlobalFITMessage SPO2 = new GlobalFITMessage(269, "SPO2", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.UINT8, "reading_spo2"),
new FieldDefinitionPrimitive(1, BaseType.UINT8, "reading_confidence"),
new FieldDefinitionPrimitive(2, BaseType.UINT8, "mode"), // 3 periodic
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
));
public static GlobalFITMessage SLEEP_STAGE = new GlobalFITMessage(275, "SLEEP_STAGE", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.ENUM, "sleep_stage", FieldDefinitionFactory.FIELD.SLEEP_STAGE),
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
));
public static GlobalFITMessage RESPIRATION_RATE = new GlobalFITMessage(297, "RESPIRATION_RATE", Arrays.asList(
new FieldDefinitionPrimitive(0, BaseType.SINT16, "respiration_rate"), // breaths / min, scaled by 100
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
));
public static GlobalFITMessage SLEEP_STATS = new GlobalFITMessage(346, "SLEEP_STATS", Arrays.asList(
));
@ -193,7 +216,9 @@ public class GlobalFITMessage {
put(207, DEVELOPER_DATA);
put(222, ALARM_SETTINGS);
put(227, STRESS_LEVEL);
put(269, SPO2);
put(275, SLEEP_STAGE);
put(297, RESPIRATION_RATE);
put(346, SLEEP_STATS);
}};
private final int number;
@ -237,32 +262,21 @@ public class GlobalFITMessage {
for (FieldDefinitionPrimitive fieldDefinitionPrimitive :
fieldDefinitionPrimitives) {
if (fieldDefinitionPrimitive.number == id) {
subset.add(FieldDefinitionFactory.create(fieldDefinitionPrimitive.number, fieldDefinitionPrimitive.size, fieldDefinitionPrimitive.type, fieldDefinitionPrimitive.baseType, fieldDefinitionPrimitive.name, fieldDefinitionPrimitive.scale, fieldDefinitionPrimitive.offset));
subset.add(FieldDefinitionFactory.create(
fieldDefinitionPrimitive.number,
fieldDefinitionPrimitive.size,
fieldDefinitionPrimitive.type,
fieldDefinitionPrimitive.baseType,
fieldDefinitionPrimitive.name,
fieldDefinitionPrimitive.scale,
fieldDefinitionPrimitive.offset
));
}
}
}
return subset;
}
@Nullable
public FieldDefinition getFieldDefinition(String name) {
for (FieldDefinitionPrimitive fieldDefinitionPrimitive :
fieldDefinitionPrimitives) {
if (fieldDefinitionPrimitive.name.equals(name)) {
return FieldDefinitionFactory.create(
fieldDefinitionPrimitive.number,
fieldDefinitionPrimitive.size,
fieldDefinitionPrimitive.type,
fieldDefinitionPrimitive.baseType,
fieldDefinitionPrimitive.name,
fieldDefinitionPrimitive.scale,
fieldDefinitionPrimitive.offset
);
}
}
return null;
}
@Nullable
public FieldDefinition getFieldDefinition(int id, int size) {
if (null == fieldDefinitionPrimitives)
@ -270,7 +284,15 @@ public class GlobalFITMessage {
for (GlobalFITMessage.FieldDefinitionPrimitive fieldDefinitionPrimitive :
fieldDefinitionPrimitives) {
if (fieldDefinitionPrimitive.number == id) {
return FieldDefinitionFactory.create(fieldDefinitionPrimitive.number, size, fieldDefinitionPrimitive.type, fieldDefinitionPrimitive.baseType, fieldDefinitionPrimitive.name, fieldDefinitionPrimitive.scale, fieldDefinitionPrimitive.offset);
return FieldDefinitionFactory.create(
fieldDefinitionPrimitive.number,
size,
fieldDefinitionPrimitive.type,
fieldDefinitionPrimitive.baseType,
fieldDefinitionPrimitive.name,
fieldDefinitionPrimitive.scale,
fieldDefinitionPrimitive.offset
);
}
}
return null;

View File

@ -161,7 +161,7 @@ public class FitCodeGen {
sb.append("\n");
sb.append(" final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();\n");
sb.append(" if (globalNumber != ").append(globalFITMessage.getNumber()).append(") {\n");
sb.append(" throw new IllegalArgumentException(\"FitFileId expects global messages of \" + ").append(globalFITMessage.getNumber()).append(" + \", got \" + globalNumber);\n");
sb.append(" throw new IllegalArgumentException(\"").append(className).append(" expects global messages of \" + ").append(globalFITMessage.getNumber()).append(" + \", got \" + globalNumber);\n");
sb.append(" }\n");
sb.append(" }\n");

View File

@ -18,7 +18,7 @@ public class FitAlarmSettings extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 222) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 222 + ", got " + globalNumber);
throw new IllegalArgumentException("FitAlarmSettings expects global messages of " + 222 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitConnectivity extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 127) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 127 + ", got " + globalNumber);
throw new IllegalArgumentException("FitConnectivity expects global messages of " + 127 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitDeveloperData extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 207) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 207 + ", got " + globalNumber);
throw new IllegalArgumentException("FitDeveloperData expects global messages of " + 207 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitDeviceInfo extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 23) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 23 + ", got " + globalNumber);
throw new IllegalArgumentException("FitDeviceInfo expects global messages of " + 23 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitDeviceSettings extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 2) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 2 + ", got " + globalNumber);
throw new IllegalArgumentException("FitDeviceSettings expects global messages of " + 2 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitFieldDescription extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 206) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 206 + ", got " + globalNumber);
throw new IllegalArgumentException("FitFieldDescription expects global messages of " + 206 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitFileCreator extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 49) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 49 + ", got " + globalNumber);
throw new IllegalArgumentException("FitFileCreator expects global messages of " + 49 + ", got " + globalNumber);
}
}

View File

@ -18,7 +18,7 @@ public class FitGoals extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 15) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 15 + ", got " + globalNumber);
throw new IllegalArgumentException("FitGoals expects global messages of " + 15 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitMonitoring extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 55) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 55 + ", got " + globalNumber);
throw new IllegalArgumentException("FitMonitoring expects global messages of " + 55 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitRecord extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 20) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 20 + ", got " + globalNumber);
throw new IllegalArgumentException("FitRecord expects global messages of " + 20 + ", got " + globalNumber);
}
}

View File

@ -49,8 +49,12 @@ public class FitRecordDataFactory {
return new FitAlarmSettings(recordDefinition, recordHeader);
case 227:
return new FitStressLevel(recordDefinition, recordHeader);
case 269:
return new FitSpo2(recordDefinition, recordHeader);
case 275:
return new FitSleepStage(recordDefinition, recordHeader);
case 297:
return new FitRespirationRate(recordDefinition, recordHeader);
case 346:
return new FitSleepStats(recordDefinition, recordHeader);
}

View File

@ -0,0 +1,32 @@
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 FitRespirationRate extends RecordData {
public FitRespirationRate(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
super(recordDefinition, recordHeader);
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 297) {
throw new IllegalArgumentException("FitRespirationRate expects global messages of " + 297 + ", got " + globalNumber);
}
}
@Nullable
public Integer getRespirationRate() {
return (Integer) getFieldByNumber(0);
}
@Nullable
public Long getTimestamp() {
return (Long) getFieldByNumber(253);
}
}

View File

@ -17,7 +17,7 @@ public class FitSleepStage extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 275) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 275 + ", got " + globalNumber);
throw new IllegalArgumentException("FitSleepStage expects global messages of " + 275 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitSleepStats extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 346) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 346 + ", got " + globalNumber);
throw new IllegalArgumentException("FitSleepStats expects global messages of " + 346 + ", got " + globalNumber);
}
}
}

View File

@ -0,0 +1,42 @@
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 FitSpo2 extends RecordData {
public FitSpo2(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
super(recordDefinition, recordHeader);
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 269) {
throw new IllegalArgumentException("FitSpo2 expects global messages of " + 269 + ", got " + globalNumber);
}
}
@Nullable
public Integer getReadingSpo2() {
return (Integer) getFieldByNumber(0);
}
@Nullable
public Integer getReadingConfidence() {
return (Integer) getFieldByNumber(1);
}
@Nullable
public Integer getMode() {
return (Integer) getFieldByNumber(2);
}
@Nullable
public Long getTimestamp() {
return (Long) getFieldByNumber(253);
}
}

View File

@ -16,7 +16,7 @@ public class FitSport extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 12) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 12 + ", got " + globalNumber);
throw new IllegalArgumentException("FitSport expects global messages of " + 12 + ", got " + globalNumber);
}
}

View File

@ -32,7 +32,7 @@ public class FitStressLevel extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 227) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 227 + ", got " + globalNumber);
throw new IllegalArgumentException("FitStressLevel expects global messages of " + 227 + ", got " + globalNumber);
}
}

View File

@ -23,7 +23,7 @@ public class FitUserProfile extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 3) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 3 + ", got " + globalNumber);
throw new IllegalArgumentException("FitUserProfile expects global messages of " + 3 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitWatchfaceSettings extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 159) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 159 + ", got " + globalNumber);
throw new IllegalArgumentException("FitWatchfaceSettings expects global messages of " + 159 + ", got " + globalNumber);
}
}

View File

@ -19,7 +19,7 @@ public class FitWeather extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 128) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 128 + ", got " + globalNumber);
throw new IllegalArgumentException("FitWeather expects global messages of " + 128 + ", got " + globalNumber);
}
}

View File

@ -16,7 +16,7 @@ public class FitZonesTarget extends RecordData {
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
if (globalNumber != 7) {
throw new IllegalArgumentException("FitFileId expects global messages of " + 7 + ", got " + globalNumber);
throw new IllegalArgumentException("FitZonesTarget expects global messages of " + 7 + ", got " + globalNumber);
}
}