From d655f434f87ebe0f4a856f34de78231ead94d54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Wed, 5 Oct 2022 22:19:08 +0100 Subject: [PATCH] Zepp OS: Display HR zones and Training Effect in Activity Details --- .../huami/Huami2021ActivitySummaryParser.java | 17 +++++- .../model/ActivitySummaryJsonSummary.java | 53 +++++++++++++------ .../gadgetbridge/util/DateTimeUtils.java | 2 +- app/src/main/res/values/strings.xml | 12 +++++ 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021ActivitySummaryParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021ActivitySummaryParser.java index 1d587cb31..bee779901 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021ActivitySummaryParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/Huami2021ActivitySummaryParser.java @@ -113,11 +113,24 @@ public class Huami2021ActivitySummaryParser extends HuamiActivitySummaryParser { } if (summaryProto.hasHeartRateZones()) { - // TODO HR zones + // TODO hr zones bpm? + if (summaryProto.getHeartRateZones().getZoneTimeCount() == 6) { + addSummaryData("hrZoneNa", summaryProto.getHeartRateZones().getZoneTime(0), "seconds"); + addSummaryData("hrZoneWarmUp", summaryProto.getHeartRateZones().getZoneTime(1), "seconds"); + addSummaryData("hrZoneFatBurn", summaryProto.getHeartRateZones().getZoneTime(2), "seconds"); + addSummaryData("hrZoneAerobic", summaryProto.getHeartRateZones().getZoneTime(3), "seconds"); + addSummaryData("hrZoneAnaerobic", summaryProto.getHeartRateZones().getZoneTime(4), "seconds"); + addSummaryData("hrZoneExtreme", summaryProto.getHeartRateZones().getZoneTime(5), "seconds"); + } else { + LOG.warn("Unexpected number of HR zones {}", summaryProto.getHeartRateZones().getZoneTimeCount()); + } } if (summaryProto.hasTrainingEffect()) { - // TODO training effect + addSummaryData("aerobicTrainingEffect", summaryProto.getTrainingEffect().getAerobicTrainingEffect(), ""); + addSummaryData("anaerobicTrainingEffect", summaryProto.getTrainingEffect().getAnaerobicTrainingEffect(), ""); + addSummaryData("currentWorkoutLoad", summaryProto.getTrainingEffect().getCurrentWorkoutLoad(), ""); + addSummaryData("maximumOxygenUptake", summaryProto.getTrainingEffect().getMaximumOxygenUptake(), "ml/kg/min"); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java index 535ef81e3..0eb946d97 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java @@ -6,7 +6,11 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; +import java.util.List; +import java.util.Map; import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiActivitySummaryParser; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; @@ -144,20 +148,39 @@ public class ActivitySummaryJsonSummary { return defaultGroup; } private JSONObject createActivitySummaryGroups(){ - String groupDefinitions = "{'Strokes':['averageStrokeDistance','averageStrokesPerSecond','strokes'], " + - "'Swimming':['swolfIndex','swimStyle'], " + - "'Elevation':['ascentMeters','descentMeters','maxAltitude','minAltitude','averageAltitude', 'baseAltitude','ascentSeconds','descentSeconds','flatSeconds','ascentDistance','descentDistance','flatDistance'], " + - "'Speed':['averageSpeed','maxSpeed','minSpeed','averageKMPaceSeconds','minPace','maxPace','averageSpeed2','averageCadence','maxCadence','minCadence'], " + - "'Activity':['distanceMeters','steps','activeSeconds','caloriesBurnt','totalStride'," + - "'averageHR','maxHR','minHR','averageStride','maxStride','minStride'], " + - "'Laps':['averageLapPace','laps']}"; - JSONObject data = null; - try { - data = new JSONObject(groupDefinitions); - } catch (JSONException e) { - LOG.error("SportsActivity", e); - } - return data; - } + final Map> groupDefinitions = new HashMap>() {{ + put("Strokes", Arrays.asList( + "averageStrokeDistance", "averageStrokesPerSecond", "strokes" + )); + put("Swimming", Arrays.asList( + "swolfIndex", "swimStyle" + )); + put("Elevation", Arrays.asList( + "ascentMeters", "descentMeters", "maxAltitude", "minAltitude", "averageAltitude", + "baseAltitude", "ascentSeconds", "descentSeconds", "flatSeconds", "ascentDistance", + "descentDistance", "flatDistance" + )); + put("Speed", Arrays.asList( + "averageSpeed", "maxSpeed", "minSpeed", "averageKMPaceSeconds", "minPace", + "maxPace", "averageSpeed2", "averageCadence", "maxCadence", "minCadence" + )); + put("Activity", Arrays.asList( + "distanceMeters", "steps", "activeSeconds", "caloriesBurnt", "totalStride", + "averageHR", "maxHR", "minHR", "averageStride", "maxStride", "minStride" + )); + put("HeartRateZones", Arrays.asList( + "hrZoneNa", "hrZoneWarmUp", "hrZoneFatBurn", "hrZoneAerobic", "hrZoneAnaerobic", + "hrZoneExtreme" + )); + put("TrainingEffect", Arrays.asList( + "aerobicTrainingEffect", "anaerobicTrainingEffect", "currentWorkoutLoad", + "maximumOxygenUptake" + )); + put("Laps", Arrays.asList( + "averageLapPace", "laps" + )); + }}; + return new JSONObject(groupDefinitions); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java index d51678114..c63bee0cc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java @@ -100,7 +100,7 @@ public class DateTimeUtils { public static String formatDurationHoursMinutes(long duration, TimeUnit unit) { DurationFormatter df = DurationFormatter.Builder.SYMBOLS .maximum(TimeUnit.DAYS) - .minimum(TimeUnit.MINUTES) + .minimum(TimeUnit.SECONDS) .suppressZeros(DurationFormatter.SuppressZeros.LEADING, DurationFormatter.SuppressZeros.TRAILING) .maximumAmountOfUnitsToShow(2) .build(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7a1233a92..ef647cf8a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1374,6 +1374,18 @@ Max Heartrate Min Heartrate Pace + Heart Rate Zones + N/A + Warm-Up + Fat Burn + Aerobic + Anaerobic + Extreme + Training Effect + Aerobic Effect + Anaerobic Effect + Workout Load + Maximum Oxygen Uptake Average Stride Max Stride Min Stride