From 951d8f25b790a16b6df8afd833b53a0ecc7fbbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Wed, 3 Jan 2024 21:35:18 +0000 Subject: [PATCH] Xiaomi: Add indoor cycling --- .../xiaomi/activity/XiaomiActivityFileId.java | 1 + .../activity/impl/WorkoutSummaryParser.java | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/XiaomiActivityFileId.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/XiaomiActivityFileId.java index acb85b85b..ebd5e1160 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/XiaomiActivityFileId.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/XiaomiActivityFileId.java @@ -196,6 +196,7 @@ public class XiaomiActivityFileId implements Comparable { ACTIVITY_SLEEP(Type.ACTIVITY, 0x08), SPORTS_OUTDOOR_RUNNING(Type.SPORTS, 0x01), SPORTS_OUTDOOR_WALKING_V1(Type.SPORTS, 0x02), + SPORTS_INDOOR_CYCLING(Type.SPORTS, 0x07), SPORTS_FREESTYLE(Type.SPORTS, 0x08), SPORTS_ELLIPTICAL(Type.SPORTS, 0x0B), SPORTS_OUTDOOR_WALKING_V2(Type.SPORTS, 0x16), diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutSummaryParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutSummaryParser.java index 3264af7b4..eb4f82d5b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutSummaryParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/xiaomi/activity/impl/WorkoutSummaryParser.java @@ -100,6 +100,9 @@ public class WorkoutSummaryParser extends XiaomiActivityParser implements Activi case SPORTS_OUTDOOR_RUNNING: parseOutdoorRunning(summary, fileId, buf); break; + case SPORTS_INDOOR_CYCLING: + parseIndoorCycling(summary, fileId, buf); + break; case SPORTS_FREESTYLE: parseFreestyle(summary, fileId, buf); break; @@ -126,6 +129,54 @@ public class WorkoutSummaryParser extends XiaomiActivityParser implements Activi // TODO } + private void parseIndoorCycling(final BaseActivitySummary summary, final XiaomiActivityFileId fileId, final ByteBuffer buf) { + final JSONObject summaryData = new JSONObject(); + + final int version = fileId.getVersion(); + final int headerSize; + switch (version) { + case 8: + headerSize = 7; + break; + default: + LOG.warn("Unable to parse workout summary version {}", fileId.getVersion()); + return; + } + + final byte[] header = new byte[headerSize]; + buf.get(header); + + summary.setActivityKind(ActivityKind.TYPE_INDOOR_CYCLING); + + final int startTime = buf.getInt(); + final int endTime = buf.getInt(); + + // We don't set the start time, since we need it to match the fileId for the WorkoutGpsParser + // to find it. They also seem to match. + //summary.setStartTime(new Date(startTime * 1000L)); + summary.setEndTime(new Date(endTime * 1000L)); + + final int duration = buf.getInt(); + addSummaryData(summaryData, "activeSeconds", duration, "seconds"); + + final int distance = buf.getInt(); + addSummaryData(summaryData, "distanceMeters", distance, "meters"); + + final int calories = buf.getShort(); + addSummaryData(summaryData, "caloriesBurnt", calories, "calories_unit"); + + final int unknown1 = buf.getInt(); + + final float avgHr = buf.get() & 0xff; + final float maxHr = buf.get() & 0xff; + final float minHr = buf.get() & 0xff; + addSummaryData(summaryData, "averageHR", avgHr, "bpm"); + addSummaryData(summaryData, "maxHR", maxHr, "bpm"); + addSummaryData(summaryData, "minHR", minHr, "bpm"); + + summary.setSummaryData(summaryData.toString()); + } + private void parseFreestyle(final BaseActivitySummary summary, final XiaomiActivityFileId fileId, final ByteBuffer buf) { summary.setActivityKind(ActivityKind.TYPE_STRENGTH_TRAINING);