From 9c67a30835f07554faeaba54dd23bb3c1878d50e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Sat, 21 Sep 2024 19:14:35 +0100 Subject: [PATCH] Garmin: Persist distance and calories --- .../gadgetbridge/daogen/GBDaoGenerator.java | 4 +- .../schema/GadgetbridgeUpdate_80.java | 44 +++++++++++++++++++ .../devices/garmin/fit/FitImporter.java | 39 +++++++++++++++- 3 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_80.java diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java index a10a3c983..8360400ce 100644 --- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java +++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java @@ -46,7 +46,7 @@ public class GBDaoGenerator { public static void main(String[] args) throws Exception { - final Schema schema = new Schema(79, MAIN_PACKAGE + ".entities"); + final Schema schema = new Schema(80, MAIN_PACKAGE + ".entities"); Entity userAttributes = addUserAttributes(schema); Entity user = addUserInfo(schema, userAttributes); @@ -753,6 +753,8 @@ public class GBDaoGenerator { activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE); activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE); addHeartRateProperties(activitySample); + activitySample.addIntProperty("distanceCm").notNull().codeBeforeGetterAndSetter(OVERRIDE); + activitySample.addIntProperty("activeCalories").notNull().codeBeforeGetterAndSetter(OVERRIDE); return activitySample; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_80.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_80.java new file mode 100644 index 000000000..077dcd234 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_80.java @@ -0,0 +1,44 @@ +/* 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 . */ +package nodomain.freeyourgadget.gadgetbridge.database.schema; + +import android.database.sqlite.SQLiteDatabase; + +import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript; +import nodomain.freeyourgadget.gadgetbridge.entities.GarminActivitySampleDao; + +public class GadgetbridgeUpdate_80 implements DBUpdateScript { + @Override + public void upgradeSchema(final SQLiteDatabase db) { + if (!DBHelper.existsColumn(GarminActivitySampleDao.TABLENAME, GarminActivitySampleDao.Properties.DistanceCm.columnName, db)) { + final String statement = "ALTER TABLE " + GarminActivitySampleDao.TABLENAME + " ADD COLUMN \"" + + GarminActivitySampleDao.Properties.DistanceCm.columnName + "\" INTEGER NOT NULL DEFAULT -1"; + db.execSQL(statement); + } + + if (!DBHelper.existsColumn(GarminActivitySampleDao.TABLENAME, GarminActivitySampleDao.Properties.ActiveCalories.columnName, db)) { + final String statement = "ALTER TABLE " + GarminActivitySampleDao.TABLENAME + " ADD COLUMN \"" + + GarminActivitySampleDao.Properties.ActiveCalories.columnName + "\" INTEGER NOT NULL DEFAULT -1"; + db.execSQL(statement); + } + } + + @Override + public void downgradeSchema(final SQLiteDatabase db) { + } +} 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 6dc42d9b8..c9d9148e4 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 @@ -356,9 +356,11 @@ public class FitImporter { final List activitySamples = new ArrayList<>(activitySamplesPerTimestamp.size()); - // Garmin reports the cumulative steps per activity, but not always, so we need to keep - // track of the number of steps for each activity, and set the sum of all on the sample + // Garmin reports the cumulative data per activity, but not always, so we need to keep + // track of the amounts for each activity, and set the sum of all on the sample final Map stepsPerActivity = new HashMap<>(); + final Map distancePerActivity = new HashMap<>(); + final Map caloriesPerActivity = new HashMap<>(); final int THRESHOLD_NOT_WORN = 10 * 60; // 10 min gap between samples = not-worn int prevActivityKind = ActivityKind.UNKNOWN.getCode(); @@ -374,6 +376,9 @@ public class FitImporter { sample.setRawKind(ts - prevTs > THRESHOLD_NOT_WORN ? ActivityKind.NOT_WORN.getCode() : prevActivityKind); sample.setRawIntensity(ActivitySample.NOT_MEASURED); sample.setSteps(ActivitySample.NOT_MEASURED); + sample.setHeartRate(ActivitySample.NOT_MEASURED); + sample.setDistanceCm(ActivitySample.NOT_MEASURED); + sample.setActiveCalories(ActivitySample.NOT_MEASURED); activitySamples.add(sample); } } @@ -386,8 +391,12 @@ public class FitImporter { sample.setRawIntensity(ActivitySample.NOT_MEASURED); sample.setSteps(ActivitySample.NOT_MEASURED); sample.setHeartRate(ActivitySample.NOT_MEASURED); + sample.setDistanceCm(ActivitySample.NOT_MEASURED); + sample.setActiveCalories(ActivitySample.NOT_MEASURED); boolean hasSteps = false; + boolean hasDistance = false; + boolean hasCalories = false; for (final FitMonitoring record : Objects.requireNonNull(records)) { final Integer activityType = record.getComputedActivityType().orElse(ActivitySample.NOT_MEASURED); @@ -402,6 +411,18 @@ public class FitImporter { hasSteps = true; } + final Long distance = record.getDistance(); + if (distance != null) { + distancePerActivity.put(activityType, distance); + hasDistance = true; + } + + final Integer calories = record.getActiveCalories(); + if (calories != null) { + caloriesPerActivity.put(activityType, calories); + hasCalories = true; + } + final Integer intensity = record.getComputedIntensity(); if (intensity != null) { sample.setRawIntensity(intensity); @@ -414,6 +435,20 @@ public class FitImporter { } sample.setSteps(sumSteps); } + if (hasDistance) { + int sumDistance = 0; + for (final Long distance : distancePerActivity.values()) { + sumDistance += distance; + } + sample.setDistanceCm(sumDistance); + } + if (hasCalories) { + int sumCalories = 0; + for (final Integer calories : caloriesPerActivity.values()) { + sumCalories += calories; + } + sample.setActiveCalories(sumCalories); + } activitySamples.add(sample);