From 9d966c81790fc5a75778e7449ed768360608c741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Tue, 23 May 2023 22:35:24 +0100 Subject: [PATCH] Huami: Add max HR fetch operation (no db persistence) --- .../devices/huami/HuamiService.java | 1 + .../FetchMaxHeartRateOperation.java | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchMaxHeartRateOperation.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java index cc624e679..aebd31242 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/HuamiService.java @@ -231,6 +231,7 @@ public class HuamiService { public static final byte COMMAND_ACTIVITY_DATA_TYPE_SPO2_SLEEP = 0x26; public static final byte COMMAND_ACTIVITY_DATA_TYPE_SLEEP_RESPIRATORY_RATE = 0x38; public static final byte COMMAND_ACTIVITY_DATA_TYPE_RESTING_HEART_RATE = 0x3a; + public static final byte COMMAND_ACTIVITY_DATA_TYPE_MAX_HEART_RATE = 0x3d; public static final byte COMMAND_FIRMWARE_INIT = 0x01; // to UUID_CHARACTERISTIC_FIRMWARE, followed by fw file size in bytes public static final byte COMMAND_FIRMWARE_START_DATA = 0x03; // to UUID_CHARACTERISTIC_FIRMWARE diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchMaxHeartRateOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchMaxHeartRateOperation.java new file mode 100644 index 000000000..0f255de1d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchMaxHeartRateOperation.java @@ -0,0 +1,68 @@ +/* Copyright (C) 2023 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.service.devices.huami.operations; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.GregorianCalendar; + +import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; + +/** + * An operation that fetches max HR data. + */ +public class FetchMaxHeartRateOperation extends AbstractRepeatingFetchOperation { + private static final Logger LOG = LoggerFactory.getLogger(FetchMaxHeartRateOperation.class); + + public FetchMaxHeartRateOperation(final HuamiSupport support) { + super(support, HuamiService.COMMAND_ACTIVITY_DATA_TYPE_MAX_HEART_RATE, "max hr data"); + } + + @Override + protected boolean handleActivityData(final GregorianCalendar timestamp, final byte[] bytes) { + if (bytes.length % 6 != 0) { + LOG.warn("Unexpected buffered max heart rate data size {} is not a multiple of 6", bytes.length); + return false; + } + + final ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); + + while (buffer.position() < bytes.length) { + final long currentTimestamp = BLETypeConversions.toUnsigned(buffer.getInt()) * 1000; + timestamp.setTimeInMillis(currentTimestamp); + + final byte utcOffsetInQuarterHours = buffer.get(); + final int hr = buffer.get() & 0xff; + + LOG.debug("Max HR at {} + {}: {}", timestamp.getTime(), utcOffsetInQuarterHours, hr); + + // TODO: Save max hr data + } + + return true; + } + + @Override + protected String getLastSyncTimeKey() { + return "lastMaxHeartRateTimeMillis"; + } +}