mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 18:15:49 +01:00
Garmin: Parse and persist HRV_STATUS
This commit is contained in:
parent
532c545093
commit
b33ab0b1c8
@ -45,7 +45,7 @@ public class GBDaoGenerator {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Schema schema = new Schema(74, MAIN_PACKAGE + ".entities");
|
||||
final Schema schema = new Schema(75, MAIN_PACKAGE + ".entities");
|
||||
|
||||
Entity userAttributes = addUserAttributes(schema);
|
||||
Entity user = addUserInfo(schema, userAttributes);
|
||||
@ -113,6 +113,8 @@ public class GBDaoGenerator {
|
||||
addGarminSpo2Sample(schema, user, device);
|
||||
addGarminSleepStageSample(schema, user, device);
|
||||
addGarminEventSample(schema, user, device);
|
||||
addGarminHrvSummarySample(schema, user, device);
|
||||
addGarminHrvValueSample(schema, user, device);
|
||||
addWena3EnergySample(schema, user, device);
|
||||
addWena3BehaviorSample(schema, user, device);
|
||||
addWena3CaloriesSample(schema, user, device);
|
||||
@ -725,6 +727,26 @@ public class GBDaoGenerator {
|
||||
return sleepStageSample;
|
||||
}
|
||||
|
||||
private static Entity addGarminHrvSummarySample(Schema schema, Entity user, Entity device) {
|
||||
Entity hrvSummarySample = addEntity(schema, "GarminHrvSummarySample");
|
||||
addCommonTimeSampleProperties("AbstractHrvSummarySample", hrvSummarySample, user, device);
|
||||
hrvSummarySample.addIntProperty("weeklyAverage").codeBeforeGetter(OVERRIDE);
|
||||
hrvSummarySample.addIntProperty("lastNightAverage").codeBeforeGetter(OVERRIDE);
|
||||
hrvSummarySample.addIntProperty("lastNight5MinHigh").codeBeforeGetter(OVERRIDE);
|
||||
hrvSummarySample.addIntProperty("baselineLowUpper").codeBeforeGetter(OVERRIDE);
|
||||
hrvSummarySample.addIntProperty("baselineBalancedLower").codeBeforeGetter(OVERRIDE);
|
||||
hrvSummarySample.addIntProperty("baselineBalancedUpper").codeBeforeGetter(OVERRIDE);
|
||||
hrvSummarySample.addIntProperty("statusNum").codeBeforeGetter(OVERRIDE);
|
||||
return hrvSummarySample;
|
||||
}
|
||||
|
||||
private static Entity addGarminHrvValueSample(Schema schema, Entity user, Entity device) {
|
||||
Entity hrvValueSample = addEntity(schema, "GarminHrvValueSample");
|
||||
addCommonTimeSampleProperties("AbstractHrvValueSample", hrvValueSample, user, device);
|
||||
hrvValueSample.addIntProperty("value").notNull().codeBeforeGetter(OVERRIDE);
|
||||
return hrvValueSample;
|
||||
}
|
||||
|
||||
private static Entity addWatchXPlusHealthActivitySample(Schema schema, Entity user, Entity device) {
|
||||
Entity activitySample = addEntity(schema, "WatchXPlusActivitySample");
|
||||
activitySample.implementsSerializable();
|
||||
|
@ -73,6 +73,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.PaiSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.SleepRespiratoryRateSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
@ -208,6 +210,16 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends HrvSummarySample> getHrvSummarySampleProvider(GBDevice device, DaoSession session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends HrvValueSample> getHrvValueSampleProvider(GBDevice device, DaoSession session) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getStressRanges() {
|
||||
// 0-39 = relaxed
|
||||
@ -442,6 +454,11 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHrvMeasurement() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsActivityTabs() {
|
||||
return supportsActivityTracking();
|
||||
|
@ -52,6 +52,8 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.PaiSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.SleepRespiratoryRateSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
@ -214,6 +216,8 @@ public interface DeviceCoordinator {
|
||||
*/
|
||||
boolean supportsStressMeasurement();
|
||||
|
||||
boolean supportsHrvMeasurement();
|
||||
|
||||
boolean supportsSleepMeasurement();
|
||||
boolean supportsStepCounter();
|
||||
boolean supportsSpeedzones();
|
||||
@ -283,6 +287,16 @@ public interface DeviceCoordinator {
|
||||
*/
|
||||
TimeSampleProvider<? extends StressSample> getStressSampleProvider(GBDevice device, DaoSession session);
|
||||
|
||||
/**
|
||||
* Returns the sample provider for HRV summary, for the device being supported.
|
||||
*/
|
||||
TimeSampleProvider<? extends HrvSummarySample> getHrvSummarySampleProvider(GBDevice device, DaoSession session);
|
||||
|
||||
/**
|
||||
* Returns the sample provider for HRV values, for the device being supported.
|
||||
*/
|
||||
TimeSampleProvider<? extends HrvValueSample> getHrvValueSampleProvider(GBDevice device, DaoSession session);
|
||||
|
||||
/**
|
||||
* Returns the stress ranges (relaxed, mild, moderate, high), so that stress can be categorized.
|
||||
*/
|
||||
|
@ -24,6 +24,8 @@ import nodomain.freeyourgadget.gadgetbridge.entities.GarminSpo2SampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminStressSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.StressSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
@ -96,6 +98,16 @@ public abstract class GarminCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
return new GarminStressSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends HrvSummarySample> getHrvSummarySampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return new GarminHrvSummarySampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends HrvValueSample> getHrvValueSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return new GarminHrvValueSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends Spo2Sample> getSpo2SampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return new GarminSpo2SampleProvider(device, session);
|
||||
@ -162,6 +174,11 @@ public abstract class GarminCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHrvMeasurement() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getStressRanges() {
|
||||
// 1-25 = relaxed
|
||||
|
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2024 José Rebelo
|
||||
|
||||
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.devices.garmin;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractTimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvSummarySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class GarminHrvSummarySampleProvider extends AbstractTimeSampleProvider<GarminHrvSummarySample> {
|
||||
public GarminHrvSummarySampleProvider(final GBDevice device, final DaoSession session) {
|
||||
super(device, session);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AbstractDao<GarminHrvSummarySample, ?> getSampleDao() {
|
||||
return getSession().getGarminHrvSummarySampleDao();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getTimestampSampleProperty() {
|
||||
return GarminHrvSummarySampleDao.Properties.Timestamp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getDeviceIdentifierSampleProperty() {
|
||||
return GarminHrvSummarySampleDao.Properties.DeviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GarminHrvSummarySample createSample() {
|
||||
return new GarminHrvSummarySample();
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2024 José Rebelo
|
||||
|
||||
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.devices.garmin;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import de.greenrobot.dao.AbstractDao;
|
||||
import de.greenrobot.dao.Property;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractTimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvValueSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class GarminHrvValueSampleProvider extends AbstractTimeSampleProvider<GarminHrvValueSample> {
|
||||
public GarminHrvValueSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
super(device, session);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AbstractDao<GarminHrvValueSample, ?> getSampleDao() {
|
||||
return getSession().getGarminHrvValueSampleDao();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getTimestampSampleProperty() {
|
||||
return GarminHrvValueSampleDao.Properties.Timestamp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getDeviceIdentifierSampleProperty() {
|
||||
return GarminHrvValueSampleDao.Properties.DeviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GarminHrvValueSample createSample() {
|
||||
return new GarminHrvValueSample();
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2024 José Rebelo
|
||||
|
||||
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.entities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
|
||||
public abstract class AbstractHrvSummarySample extends AbstractTimeSample implements HrvSummarySample {
|
||||
public Integer getStatusNum() {
|
||||
return Status.NONE.getNum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return Status.fromNum(getStatusNum());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "{" +
|
||||
"timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimestampMillis(getTimestamp())) +
|
||||
", weeklyAverage=" + getWeeklyAverage() +
|
||||
", lastNightAverage=" + getLastNightAverage() +
|
||||
", lastNight5MinHigh=" + getLastNight5MinHigh() +
|
||||
", baselineLowUpper=" + getBaselineLowUpper() +
|
||||
", baselineBalancedLower=" + getBaselineBalancedLower() +
|
||||
", baselineBalancedUpper=" + getBaselineBalancedUpper() +
|
||||
", status=" + getStatus() +
|
||||
", userId=" + getUserId() +
|
||||
", deviceId=" + getDeviceId() +
|
||||
"}";
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2024 José Rebelo
|
||||
|
||||
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.entities;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.HrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
|
||||
public abstract class AbstractHrvValueSample extends AbstractTimeSample implements HrvValueSample {
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "{" +
|
||||
"timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimestampMillis(getTimestamp())) +
|
||||
", value=" + getValue() +
|
||||
", userId=" + getUserId() +
|
||||
", deviceId=" + getDeviceId() +
|
||||
"}";
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/* Copyright (C) 2024 José Rebelo
|
||||
|
||||
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.model;
|
||||
|
||||
public interface HrvSummarySample extends TimeSample {
|
||||
enum Status {
|
||||
NONE(0),
|
||||
POOR(1),
|
||||
LOW(2),
|
||||
UNBALANCED(3),
|
||||
BALANCED(4),
|
||||
;
|
||||
|
||||
private final int num;
|
||||
|
||||
Status(final int num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public int getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public static Status fromNum(final int num) {
|
||||
for (Status value : Status.values()) {
|
||||
if (value.getNum() == num) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown hrv status num " + num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Weekly average, in milliseconds.
|
||||
*/
|
||||
Integer getWeeklyAverage();
|
||||
|
||||
/**
|
||||
* Last night average, in milliseconds.
|
||||
*/
|
||||
Integer getLastNightAverage();
|
||||
|
||||
/**
|
||||
* Last night 5-min high, in milliseconds.
|
||||
*/
|
||||
Integer getLastNight5MinHigh();
|
||||
|
||||
/**
|
||||
* Baseline low upper, in milliseconds.
|
||||
*/
|
||||
Integer getBaselineLowUpper();
|
||||
|
||||
/**
|
||||
* Baseline balanced lower, in milliseconds.
|
||||
*/
|
||||
Integer getBaselineBalancedLower();
|
||||
|
||||
/**
|
||||
* Baseline balanced upper, in milliseconds.
|
||||
*/
|
||||
Integer getBaselineBalancedUpper();
|
||||
|
||||
Status getStatus();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/* Copyright (C) 2024 José Rebelo
|
||||
|
||||
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.model;
|
||||
|
||||
public interface HrvValueSample extends TimeSample {
|
||||
/**
|
||||
* HRV value, in milliseconds.
|
||||
*/
|
||||
int getValue();
|
||||
}
|
@ -6,6 +6,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefi
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionFileType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionGoalSource;
|
||||
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.FieldDefinitionLanguage;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionSleepStage;
|
||||
@ -30,6 +31,8 @@ public class FieldDefinitionFactory {
|
||||
return new FieldDefinitionGoalSource(localNumber, size, baseType, name);
|
||||
case GOAL_TYPE:
|
||||
return new FieldDefinitionGoalType(localNumber, size, baseType, name);
|
||||
case HRV_STATUS:
|
||||
return new FieldDefinitionHrvStatus(localNumber, size, baseType, name);
|
||||
case MEASUREMENT_SYSTEM:
|
||||
return new FieldDefinitionMeasurementSystem(localNumber, size, baseType, name);
|
||||
case TEMPERATURE:
|
||||
@ -55,6 +58,7 @@ public class FieldDefinitionFactory {
|
||||
FILE_TYPE,
|
||||
GOAL_SOURCE,
|
||||
GOAL_TYPE,
|
||||
HRV_STATUS,
|
||||
MEASUREMENT_SYSTEM,
|
||||
TEMPERATURE,
|
||||
TIMESTAMP,
|
||||
|
@ -32,6 +32,8 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminActivitySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminEventSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminHrvSummarySampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminHrvValueSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSleepStageSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSpo2SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminStressSampleProvider;
|
||||
@ -40,6 +42,8 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminEventSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvSummarySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvValueSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminSleepStageSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminSpo2Sample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GarminStressSample;
|
||||
@ -51,9 +55,12 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData;
|
||||
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.FieldDefinitionHrvStatus;
|
||||
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.FitFileId;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitHrvSummary;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitHrvValue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitMonitoring;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitRecord;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitSession;
|
||||
@ -75,6 +82,8 @@ public class FitImporter {
|
||||
private final List<GarminSpo2Sample> spo2samples = new ArrayList<>();
|
||||
private final List<GarminEventSample> events = new ArrayList<>();
|
||||
private final List<GarminSleepStageSample> sleepStageSamples = new ArrayList<>();
|
||||
private final List<GarminHrvSummarySample> hrvSummarySamples = new ArrayList<>();
|
||||
private final List<GarminHrvValueSample> hrvValueSamples = new ArrayList<>();
|
||||
private final List<FitTimeInZone> timesInZone = new ArrayList<>();
|
||||
private final List<ActivityPoint> activityPoints = new ArrayList<>();
|
||||
private final Map<Integer, Integer> unknownRecords = new HashMap<>();
|
||||
@ -179,6 +188,34 @@ public class FitImporter {
|
||||
} else if (record instanceof FitTimeInZone) {
|
||||
LOG.trace("Time in zone: {}", record);
|
||||
timesInZone.add((FitTimeInZone) record);
|
||||
} else if (record instanceof FitHrvSummary) {
|
||||
final FitHrvSummary hrvSummary = (FitHrvSummary) record;
|
||||
final FieldDefinitionHrvStatus.HrvStatus status = hrvSummary.getStatus();
|
||||
if (status == null) {
|
||||
continue;
|
||||
}
|
||||
LOG.trace("HRV summary at {}: {}", ts, record);
|
||||
final GarminHrvSummarySample sample = new GarminHrvSummarySample( );
|
||||
sample.setTimestamp(ts * 1000L);
|
||||
sample.setWeeklyAverage(hrvSummary.getWeeklyAverage());
|
||||
sample.setLastNightAverage(hrvSummary.getLastNightAverage());
|
||||
sample.setLastNight5MinHigh(hrvSummary.getLastNight5MinHigh());
|
||||
sample.setBaselineLowUpper(hrvSummary.getBaselineLowUpper());
|
||||
sample.setBaselineBalancedLower(hrvSummary.getBaselineBalancedLower());
|
||||
sample.setBaselineBalancedUpper(hrvSummary.getBaselineBalancedUpper());
|
||||
sample.setStatusNum(status.getId());
|
||||
hrvSummarySamples.add(sample);
|
||||
} else if (record instanceof FitHrvValue) {
|
||||
final FitHrvValue hrvValue = (FitHrvValue) record;
|
||||
if (hrvValue.getValue() == null) {
|
||||
LOG.warn("HRV value at {} is null", ts);
|
||||
continue;
|
||||
}
|
||||
LOG.trace("HRV value at {}: {}", ts, hrvValue.getValue());
|
||||
final GarminHrvValueSample sample = new GarminHrvValueSample();
|
||||
sample.setTimestamp(ts * 1000L);
|
||||
sample.setValue(hrvValue.getValue());
|
||||
hrvValueSamples.add(sample);
|
||||
} else {
|
||||
LOG.trace("Unknown record: {}", record);
|
||||
|
||||
@ -202,18 +239,22 @@ public class FitImporter {
|
||||
}
|
||||
|
||||
switch (fileId.getType()) {
|
||||
case activity:
|
||||
case ACTIVITY:
|
||||
persistWorkout(file);
|
||||
break;
|
||||
case monitor:
|
||||
case MONITOR:
|
||||
persistActivitySamples();
|
||||
persistSpo2Samples();
|
||||
persistStressSamples();
|
||||
break;
|
||||
case sleep:
|
||||
case SLEEP:
|
||||
persistEvents();
|
||||
persistSleepStageSamples();
|
||||
break;
|
||||
case HRV_STATUS:
|
||||
persistHrvSummarySamples();
|
||||
persistHrvValueSamples();
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unable to handle fit file of type {}", fileId.getType());
|
||||
}
|
||||
@ -512,6 +553,58 @@ public class FitImporter {
|
||||
}
|
||||
}
|
||||
|
||||
private void persistHrvSummarySamples() {
|
||||
if (hrvSummarySamples.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debug("Will persist {} HRV summary samples", hrvSummarySamples.size());
|
||||
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
|
||||
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||
final User user = DBHelper.getUser(session);
|
||||
|
||||
final GarminHrvSummarySampleProvider sampleProvider = new GarminHrvSummarySampleProvider(gbDevice, session);
|
||||
|
||||
for (final GarminHrvSummarySample sample : hrvSummarySamples) {
|
||||
sample.setDevice(device);
|
||||
sample.setUser(user);
|
||||
}
|
||||
|
||||
sampleProvider.addSamples(hrvSummarySamples);
|
||||
} catch (final Exception e) {
|
||||
GB.toast(context, "Error saving HRV summary samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void persistHrvValueSamples() {
|
||||
if (hrvValueSamples.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debug("Will persist {} HRV value samples", hrvValueSamples.size());
|
||||
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
|
||||
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||
final User user = DBHelper.getUser(session);
|
||||
|
||||
final GarminHrvValueSampleProvider sampleProvider = new GarminHrvValueSampleProvider(gbDevice, session);
|
||||
|
||||
for (final GarminHrvValueSample sample : hrvValueSamples) {
|
||||
sample.setDevice(device);
|
||||
sample.setUser(user);
|
||||
}
|
||||
|
||||
sampleProvider.addSamples(hrvValueSamples);
|
||||
} catch (final Exception e) {
|
||||
GB.toast(context, "Error saving HRV value samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void persistSpo2Samples() {
|
||||
if (spo2samples.isEmpty()) {
|
||||
return;
|
||||
|
@ -253,6 +253,22 @@ public class GlobalFITMessage {
|
||||
public static GlobalFITMessage SLEEP_STATS = new GlobalFITMessage(346, "SLEEP_STATS", Arrays.asList(
|
||||
));
|
||||
|
||||
public static GlobalFITMessage HRV_SUMMARY = new GlobalFITMessage(370, "HRV_SUMMARY", Arrays.asList(
|
||||
new FieldDefinitionPrimitive(0, BaseType.UINT16, "weekly_average", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(1, BaseType.UINT16, "last_night_average", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(2, BaseType.UINT16, "last_night_5_min_high", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(3, BaseType.UINT16, "baseline_low_upper", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(4, BaseType.UINT16, "baseline_balanced_lower", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(5, BaseType.UINT16, "baseline_balanced_upper", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(6, BaseType.ENUM, "status", FieldDefinitionFactory.FIELD.HRV_STATUS),
|
||||
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
|
||||
));
|
||||
|
||||
public static GlobalFITMessage HRV_VALUE = new GlobalFITMessage(371, "HRV_VALUE", Arrays.asList(
|
||||
new FieldDefinitionPrimitive(0, BaseType.UINT16, "value", 128, 0), // milliseconds, scaled by 128
|
||||
new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP)
|
||||
));
|
||||
|
||||
public static Map<Integer, GlobalFITMessage> KNOWN_MESSAGES = new HashMap<Integer, GlobalFITMessage>() {{
|
||||
put(0, FILE_ID);
|
||||
put(2, DEVICE_SETTINGS);
|
||||
@ -280,6 +296,8 @@ public class GlobalFITMessage {
|
||||
put(275, SLEEP_STAGE);
|
||||
put(297, RESPIRATION_RATE);
|
||||
put(346, SLEEP_STATS);
|
||||
put(370, HRV_SUMMARY);
|
||||
put(371, HRV_VALUE);
|
||||
}};
|
||||
private final int number;
|
||||
private final String name;
|
||||
|
@ -22,13 +22,14 @@ import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.FileType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.GlobalFITMessage;
|
||||
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;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionFileType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionGoalSource;
|
||||
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.FieldDefinitionLanguage;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionSleepStage;
|
||||
@ -230,11 +231,13 @@ public class FitCodeGen {
|
||||
case DAY_OF_WEEK:
|
||||
return DayOfWeek.class;
|
||||
case FILE_TYPE:
|
||||
return FieldDefinitionFileType.Type.class;
|
||||
return FileType.FILETYPE.class;
|
||||
case GOAL_SOURCE:
|
||||
return FieldDefinitionGoalSource.Source.class;
|
||||
case GOAL_TYPE:
|
||||
return FieldDefinitionGoalType.Type.class;
|
||||
case HRV_STATUS:
|
||||
return FieldDefinitionHrvStatus.HrvStatus.class;
|
||||
case MEASUREMENT_SYSTEM:
|
||||
return FieldDefinitionMeasurementSystem.Type.class;
|
||||
case TEMPERATURE:
|
||||
|
@ -1,9 +1,8 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.FileType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FieldDefinition;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.baseTypes.BaseType;
|
||||
|
||||
@ -16,47 +15,16 @@ public class FieldDefinitionFileType extends FieldDefinition {
|
||||
@Override
|
||||
public Object decode(ByteBuffer byteBuffer) {
|
||||
int raw = (int) baseType.decode(byteBuffer, scale, offset);
|
||||
return Type.fromId(raw) == null ? raw : Type.fromId(raw);
|
||||
final FileType.FILETYPE fileType = FileType.FILETYPE.fromDataTypeSubType(128, raw);
|
||||
return fileType == null ? raw : fileType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer byteBuffer, Object o) {
|
||||
if (o instanceof Type) {
|
||||
baseType.encode(byteBuffer, (((Type) o).getId()), scale, offset);
|
||||
if (o instanceof FileType.FILETYPE) {
|
||||
baseType.encode(byteBuffer, (((FileType.FILETYPE) o).getSubType()), scale, offset);
|
||||
return;
|
||||
}
|
||||
baseType.encode(byteBuffer, o, scale, offset);
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
settings(2),
|
||||
activity(4), //FIT_TYPE_4 stands for activity directory
|
||||
goals(11),
|
||||
monitor(32), //FIT_TYPE_32
|
||||
changelog(41), // FIT_TYPE_41 stands for changelog directory
|
||||
metrics(44), //FIT_TYPE_41
|
||||
sleep(49), //FIT_TYPE_49
|
||||
;
|
||||
|
||||
private final int id;
|
||||
|
||||
Type(int i) {
|
||||
this.id = i;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type fromId(int id) {
|
||||
for (Type type :
|
||||
Type.values()) {
|
||||
if (id == type.getId()) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
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 FieldDefinitionHrvStatus extends FieldDefinition {
|
||||
public FieldDefinitionHrvStatus(final int localNumber, final int size, final BaseType baseType, final String name) {
|
||||
super(localNumber, size, baseType, name, 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(final ByteBuffer byteBuffer) {
|
||||
final int raw = (int) baseType.decode(byteBuffer, scale, offset);
|
||||
return HrvStatus.fromId(raw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(final ByteBuffer byteBuffer, final Object o) {
|
||||
if (o instanceof HrvStatus) {
|
||||
baseType.encode(byteBuffer, (((HrvStatus) o).getId()), scale, offset);
|
||||
return;
|
||||
}
|
||||
baseType.encode(byteBuffer, o, scale, offset);
|
||||
}
|
||||
|
||||
public enum HrvStatus {
|
||||
NONE(0),
|
||||
POOR(1),
|
||||
LOW(2),
|
||||
UNBALANCED(3),
|
||||
BALANCED(4),
|
||||
;
|
||||
|
||||
private final int id;
|
||||
|
||||
HrvStatus(final int i) {
|
||||
id = i;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HrvStatus fromId(final int id) {
|
||||
for (HrvStatus stage : HrvStatus.values()) {
|
||||
if (id == stage.getId()) {
|
||||
return stage;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,10 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.FileType.FILETYPE;
|
||||
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;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionFileType.Type;
|
||||
|
||||
//
|
||||
// WARNING: This class was auto-generated, please avoid modifying it directly.
|
||||
@ -22,8 +22,8 @@ public class FitFileId extends RecordData {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Type getType() {
|
||||
return (Type) getFieldByNumber(0);
|
||||
public FILETYPE getType() {
|
||||
return (FILETYPE) getFieldByNumber(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -0,0 +1,63 @@
|
||||
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;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionHrvStatus.HrvStatus;
|
||||
|
||||
//
|
||||
// WARNING: This class was auto-generated, please avoid modifying it directly.
|
||||
// See nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen
|
||||
//
|
||||
public class FitHrvSummary extends RecordData {
|
||||
public FitHrvSummary(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
|
||||
super(recordDefinition, recordHeader);
|
||||
|
||||
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
|
||||
if (globalNumber != 370) {
|
||||
throw new IllegalArgumentException("FitHrvSummary expects global messages of " + 370 + ", got " + globalNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getWeeklyAverage() {
|
||||
return (Integer) getFieldByNumber(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getLastNightAverage() {
|
||||
return (Integer) getFieldByNumber(1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getLastNight5MinHigh() {
|
||||
return (Integer) getFieldByNumber(2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getBaselineLowUpper() {
|
||||
return (Integer) getFieldByNumber(3);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getBaselineBalancedLower() {
|
||||
return (Integer) getFieldByNumber(4);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getBaselineBalancedUpper() {
|
||||
return (Integer) getFieldByNumber(5);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public HrvStatus getStatus() {
|
||||
return (HrvStatus) getFieldByNumber(6);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTimestamp() {
|
||||
return (Long) getFieldByNumber(253);
|
||||
}
|
||||
}
|
@ -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 FitHrvValue extends RecordData {
|
||||
public FitHrvValue(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
|
||||
super(recordDefinition, recordHeader);
|
||||
|
||||
final int globalNumber = recordDefinition.getGlobalFITMessage().getNumber();
|
||||
if (globalNumber != 371) {
|
||||
throw new IllegalArgumentException("FitHrvValue expects global messages of " + 371 + ", got " + globalNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getValue() {
|
||||
return (Integer) getFieldByNumber(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTimestamp() {
|
||||
return (Long) getFieldByNumber(253);
|
||||
}
|
||||
}
|
@ -67,6 +67,10 @@ public class FitRecordDataFactory {
|
||||
return new FitRespirationRate(recordDefinition, recordHeader);
|
||||
case 346:
|
||||
return new FitSleepStats(recordDefinition, recordHeader);
|
||||
case 370:
|
||||
return new FitHrvSummary(recordDefinition, recordHeader);
|
||||
case 371:
|
||||
return new FitHrvValue(recordDefinition, recordHeader);
|
||||
}
|
||||
|
||||
return new RecordData(recordDefinition, recordHeader);
|
||||
|
Loading…
Reference in New Issue
Block a user