diff --git a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
index a8b381019..dd5bde65f 100644
--- a/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
+++ b/GBDaoGenerator/src/nodomain/freeyourgadget/gadgetbridge/daogen/GBDaoGenerator.java
@@ -45,7 +45,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception {
- final Schema schema = new Schema(72, MAIN_PACKAGE + ".entities");
+ final Schema schema = new Schema(73, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes);
@@ -1170,6 +1170,9 @@ public class GBDaoGenerator {
workoutDataSample.addShortProperty("calories").notNull();
workoutDataSample.addShortProperty("cyclingPower").notNull();
+ workoutDataSample.addShortProperty("frequency").notNull();
+ workoutDataSample.addIntProperty("altitude");
+
return workoutDataSample;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_73.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_73.java
new file mode 100644
index 000000000..fd486c1b2
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/database/schema/GadgetbridgeUpdate_73.java
@@ -0,0 +1,43 @@
+/* Copyright (C) 2024 Martin.JM
+
+ 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.HuaweiWorkoutDataSampleDao;
+
+public class GadgetbridgeUpdate_73 implements DBUpdateScript {
+ @Override
+ public void upgradeSchema(final SQLiteDatabase db) {
+ if (!DBHelper.existsColumn(HuaweiWorkoutDataSampleDao.TABLENAME, HuaweiWorkoutDataSampleDao.Properties.Frequency.columnName, db)) {
+ final String statement = "ALTER TABLE " + HuaweiWorkoutDataSampleDao.TABLENAME + " ADD COLUMN \""
+ + HuaweiWorkoutDataSampleDao.Properties.Frequency.columnName + "\" INTEGER NOT NULL DEFAULT -1";
+ db.execSQL(statement);
+ }
+ if (!DBHelper.existsColumn(HuaweiWorkoutDataSampleDao.TABLENAME, HuaweiWorkoutDataSampleDao.Properties.Altitude.columnName, db)) {
+ final String statement = "ALTER TABLE " + HuaweiWorkoutDataSampleDao.TABLENAME + " ADD COLUMN \""
+ + HuaweiWorkoutDataSampleDao.Properties.Altitude.columnName + "\" INTEGER DEFAULT NULL";
+ db.execSQL(statement);
+ }
+ }
+
+ @Override
+ public void downgradeSchema(final SQLiteDatabase db) {
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Workout.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Workout.java
index e725eb20e..74753e94e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Workout.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/Workout.java
@@ -241,6 +241,8 @@ public class Workout {
public short calories = -1;
public short cyclingPower = -1;
+ public short frequency = -1;
+ public Integer altitude = null;
public int timestamp = -1; // Calculated timestamp for this data point
@@ -264,6 +266,8 @@ public class Workout {
", strokeRate=" + strokeRate +
", calories=" + calories +
", cyclingPower=" + cyclingPower +
+ ", frequency=" + frequency +
+ ", altitude=" + altitude +
", timestamp=" + timestamp +
'}';
}
@@ -372,6 +376,9 @@ public class Workout {
case 4:
data.strokeRate = buf.getShort();
break;
+ case 5:
+ data.altitude = buf.getInt();
+ break;
case 6:
// Inner data, parsing into data
// TODO: function for readability?
@@ -419,6 +426,9 @@ public class Workout {
data.calories = buf.getShort();
break;
case 8:
+ data.frequency = buf.getShort();
+ break;
+ case 9:
data.cyclingPower = buf.getShort();
break;
default:
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java
index 7722676a4..33a30b309 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java
@@ -1515,7 +1515,9 @@ public class HuaweiSupportProvider {
data.strokeRate,
unknown,
data.calories,
- data.cyclingPower
+ data.cyclingPower,
+ data.frequency,
+ data.altitude
);
dao.insertOrReplace(dataSample);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWorkoutGbParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWorkoutGbParser.java
index ee552b264..d413da6af 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWorkoutGbParser.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiWorkoutGbParser.java
@@ -108,7 +108,9 @@ public class HuaweiWorkoutGbParser {
responseData.strokeRate,
dataErrorHex,
responseData.calories,
- responseData.cyclingPower
+ responseData.cyclingPower,
+ responseData.frequency,
+ responseData.altitude
);
dbHandler.getDaoSession().getHuaweiWorkoutDataSampleDao().insertOrReplace(dataSample);
@@ -308,6 +310,13 @@ public class HuaweiWorkoutGbParser {
int maxCyclingPower = 0;
int cyclingPower = 0;
int cyclingPowerCount = 0;
+ int avgAltitude = 0;
+ int altitudeCount = 0;
+ int minAltitude = 0;
+ int maxAltitude = 0;
+ Integer previousAlt = null;
+ int sumAltitudeUp = 0;
+ int sumAltitudeDown = 0;
for (HuaweiWorkoutDataSample dataSample : dataSamples) {
if (dataSample.getSpeed() != -1) {
speed += dataSample.getSpeed();
@@ -391,6 +400,22 @@ public class HuaweiWorkoutGbParser {
if (cp < minCyclingPower)
minCyclingPower = cp;
}
+ if (dataSample.getAltitude() != null) {
+ int alt = dataSample.getAltitude();
+ avgAltitude += alt;
+ altitudeCount += 1;
+ if (alt > maxAltitude)
+ maxAltitude = alt;
+ if (alt < minAltitude)
+ minAltitude = alt;
+ if (previousAlt != null) {
+ if (alt > previousAlt)
+ sumAltitudeUp += alt - previousAlt;
+ else if (alt < previousAlt)
+ sumAltitudeDown += previousAlt - alt;
+ }
+ previousAlt = alt;
+ }
if (dataSample.getDataErrorHex() != null)
unknownData = true;
}
@@ -420,6 +445,8 @@ public class HuaweiWorkoutGbParser {
heartRate = heartRate / heartRateCount;
if (cyclingPowerCount > 0)
cyclingPower = cyclingPower / cyclingPowerCount;
+ if (altitudeCount > 0)
+ avgAltitude = avgAltitude / altitudeCount;
if (speedCount > 0) {
JSONObject speedJson = new JSONObject();
@@ -578,6 +605,33 @@ public class HuaweiWorkoutGbParser {
maxCyclingPowerJson.put("unit", "");
jsonObject.put(ActivitySummaryEntries.CYCLING_POWER_MAX, maxCyclingPowerJson);
}
+
+ if (altitudeCount > 0) {
+ JSONObject avgAltitudeJson = new JSONObject();
+ avgAltitudeJson.put("value", avgAltitude);
+ avgAltitudeJson.put("unit", "");
+ jsonObject.put(ActivitySummaryEntries.ALTITUDE_AVG, avgAltitudeJson);
+
+ JSONObject minAltitudeJson = new JSONObject();
+ minAltitudeJson.put("value", minAltitude);
+ minAltitudeJson.put("unit", "");
+ jsonObject.put(ActivitySummaryEntries.ALTITUDE_MIN, minAltitudeJson);
+
+ JSONObject maxAltitudeJson = new JSONObject();
+ maxAltitudeJson.put("value", maxAltitude);
+ maxAltitudeJson.put("unit", "");
+ jsonObject.put(ActivitySummaryEntries.ALTITUDE_MAX, maxAltitudeJson);
+
+ JSONObject sumUpAltitudeJson = new JSONObject();
+ sumUpAltitudeJson.put("value", sumAltitudeUp);
+ sumUpAltitudeJson.put("unit", "");
+ jsonObject.put(ActivitySummaryEntries.ELEVATION_GAIN, sumUpAltitudeJson);
+
+ JSONObject sumDownAltitudeJson = new JSONObject();
+ sumDownAltitudeJson.put("value", sumAltitudeDown);
+ sumDownAltitudeJson.put("unit", "");
+ jsonObject.put(ActivitySummaryEntries.ELEVATION_LOSS, sumDownAltitudeJson);
+ }
}
try (CloseableListIterator it = qbPace.build().listIterator()) {
diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestWorkout.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestWorkout.java
index d29b173de..b65934e95 100644
--- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestWorkout.java
+++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/TestWorkout.java
@@ -259,6 +259,14 @@ public class TestWorkout {
byte backFootLanding2 = 0x26;
byte eversionAngle2 = 0x27;
+ // TODO: Add:
+ // - swolf
+ // - stoke rate
+ // - calories
+ // - cycling power
+ // - frequency
+ // - altitude
+
ByteBuffer headerBuf = ByteBuffer.allocate(14);
headerBuf.putShort(workoutNumber);
headerBuf.putShort(dataNumber);