From b20a9c9cccf9b577a9ac8a79bb9347f4532f6180 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sun, 23 Oct 2016 23:53:48 +0200 Subject: [PATCH] Some initial hacky support for hr readings (Debug activity only) My Mi2 stopped reporting hr values a while ago though, even on-device. --- .../profiles/heartrate/HeartRateProfile.java | 38 +++++++++++++------ .../devices/miband/MiBand2Support.java | 12 ++++-- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java index db0ff14f8..f54951240 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/heartrate/HeartRateProfile.java @@ -2,16 +2,23 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import android.widget.Toast; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile; +import nodomain.freeyourgadget.gadgetbridge.util.GB; /** * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml */ public class HeartRateProfile extends AbstractBleProfile { + private static final Logger LOG = LoggerFactory.getLogger(HeartRateProfile.class); + /** * Returned when a request to the heart rate control point is not supported by the device */ @@ -26,29 +33,36 @@ public class HeartRateProfile extends Abstr } protected void writeToControlPoint(byte value, TransactionBuilder builder) { - builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), new byte[] { value }); + writeToControlPoint(new byte[] { value }, builder); + } + + protected void writeToControlPoint(byte[] value, TransactionBuilder builder) { + builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), value); } public void requestBodySensorLocation(TransactionBuilder builder) { } + // TODO: I didn't find anything in the spec to request heart rate readings, so probably this + // should be done in a device specific way. public void requestHeartRateMeasurement(TransactionBuilder builder) { - + writeToControlPoint(new byte[] { 0x15, 0x02, 0x01}, builder); } @Override public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { -// if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) { -// int flag = characteristic.getProperties(); -// int format = -1; -// if ((flag & 0x01) != 0) { -// format = BluetoothGattCharacteristic.FORMAT_UINT16; -// } else { -// format = BluetoothGattCharacteristic.FORMAT_UINT8; -// } -// final int heartRate = characteristic.getIntValue(format, 1); -// } + if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) { + int flag = characteristic.getProperties(); + int format = -1; + if ((flag & 0x01) != 0) { + format = BluetoothGattCharacteristic.FORMAT_UINT16; + } else { + format = BluetoothGattCharacteristic.FORMAT_UINT8; + } + final int heartRate = characteristic.getIntValue(format, 1); + GB.toast(getContext(), "Heart rate: " + heartRate, Toast.LENGTH_LONG, GB.INFO); + } return false; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java index 026a186f5..16380cb5e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java @@ -57,6 +57,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWrit import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.Mi2NotificationStrategy; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.InitOperation; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; @@ -230,6 +231,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_AUTH), enable); builder.notify(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC3), enable); builder.notify(getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC4), enable); + builder.notify(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT), enable); return this; } @@ -673,12 +675,14 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { if (supportsHeartRate()) { try { TransactionBuilder builder = performInitialized("HeartRateTest"); - builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), stopHeartMeasurementContinuous); - builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), stopHeartMeasurementManual); - builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), startHeartMeasurementManual); + HeartRateProfile profile = new HeartRateProfile<>(this); + profile.requestHeartRateMeasurement(builder); +// builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), stopHeartMeasurementContinuous); +// builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), stopHeartMeasurementManual); +// builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_HEART_RATE_CONTROL_POINT), startHeartMeasurementManual); builder.queue(getQueue()); } catch (IOException ex) { - LOG.error("Unable to read HearRate in MI1S", ex); + LOG.error("Unable to read HearRate with MI2", ex); } } else { GB.toast(getContext(), "Heart rate is not supported on this device", Toast.LENGTH_LONG, GB.ERROR);