diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java
index c85a920a91..c6e0f501b4 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java
@@ -1,3 +1,19 @@
+/* Copyright (C) 2024 José Rebelo, CaptKentish, Daniele Gobbetti, 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 . */
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit;
import android.content.Context;
@@ -42,6 +58,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminStressSamplePro
import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminWorkoutParser;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractTimeSample;
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
+import nodomain.freeyourgadget.gadgetbridge.entities.BatteryLevel;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.GarminActivitySample;
@@ -70,6 +87,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.FileType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.exception.FitParseException;
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.FitDeviceStatus;
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;
@@ -119,6 +137,7 @@ public class FitImporter {
private final Map unknownRecords = new HashMap<>();
private FitSleepDataInfo fitSleepDataInfo = null;
private final List fitSleepDataRawSamples = new ArrayList<>();
+ private final List batterySamples = new ArrayList<>();
private FitFileId fileId = null;
private final GarminWorkoutParser workoutParser;
@@ -351,6 +370,15 @@ public class FitImporter {
sample.setTimestamp(ts * 1000L);
sample.setHeartRate(monitoringHrData.getRestingHeartRate());
restingHrSamples.add(sample);
+ } else if (record instanceof FitDeviceStatus deviceStatus) {
+ Integer level = deviceStatus.getBatteryLevel();
+ if (ts != null && level != null){
+ BatteryLevel batteryLevel = new BatteryLevel();
+ batteryLevel.setTimestamp(ts.intValue());
+ batteryLevel.setBatteryIndex(0);
+ batteryLevel.setLevel(level);
+ batterySamples.add(batteryLevel);
+ }
} else {
LOG.trace("Unknown record: {}", record);
@@ -443,7 +471,16 @@ public class FitImporter {
LOG.warn("Unable to handle fit file of type {}", fileId.getType());
}
} catch (final Exception e) {
- GB.toast(context, "Error saving samples", Toast.LENGTH_LONG, GB.ERROR, e);
+ GB.toast(context, "Error saving specific samples", Toast.LENGTH_LONG, GB.ERROR, e);
+ }
+
+ // these samples can occur in multiple FIT file types
+ try (DBHandler handler = GBApplication.acquireDB()) {
+ final DaoSession session = handler.getDaoSession();
+ final long deviceId = DBHelper.getDevice(gbDevice, session).getId();
+ persistBattery(session, deviceId);
+ } catch (final Exception e) {
+ GB.toast(context, "Error saving generic samples", Toast.LENGTH_LONG, GB.ERROR, e);
}
for (final Map.Entry e : unknownRecords.entrySet()) {
@@ -452,6 +489,15 @@ public class FitImporter {
}
}
+ private void persistBattery(final DaoSession session, final long deviceId) {
+ if (!batterySamples.isEmpty()) {
+ for (BatteryLevel batteryLevel : batterySamples) {
+ batteryLevel.setDeviceId(deviceId);
+ }
+ session.getBatteryLevelDao().insertOrReplaceInTx(batterySamples);
+ }
+ }
+
private void persistWorkout(final File file, final DaoSession session) {
LOG.debug("Persisting workout for {}", fileId);
@@ -505,6 +551,7 @@ public class FitImporter {
unknownRecords.clear();
fitSleepDataInfo = null;
fitSleepDataRawSamples.clear();
+ batterySamples.clear();
fileId = null;
workoutParser.reset();
}