Merge remote-tracking branch 'origin/master' into new_GUI

master
cpfeiffer 2016-10-24 11:32:39 +02:00
commit 84f36b528a
6 changed files with 58 additions and 45 deletions

View File

@ -1,5 +1,9 @@
###Changelog
####Version 0.13.6
* Mi Band 2: Support for multiple alarms (3 at the moment)
* Mi Band 2: Fix for alarms not working when just one is enabled
####Version 0.13.5
* Mi Band 2: Support setting one alarm
* Pebble: Health compatibility for Firmware 4.2

View File

@ -26,8 +26,8 @@ android {
targetSdkVersion 23
// note: always bump BOTH versionCode and versionName!
versionName "0.13.5"
versionCode 67
versionName "0.13.6"
versionCode 68
vectorDrawables.useSupportLibrary = true
}

View File

@ -16,8 +16,8 @@ public class MiBand2Service {
public static final UUID UUID_UNKNOWN_CHARACTERISTIC0 = UUID.fromString("00000000-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC1 = UUID.fromString("00000001-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC2 = UUID.fromString("00000002-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC3 = UUID.fromString("00000003-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC4 = UUID.fromString("00000004-0000-3512-2118-0009af100700"); // Alarm related
public static final UUID UUID_UNKNOWN_CHARACTERISTIC3 = UUID.fromString("00000003-0000-3512-2118-0009af100700"); // Alarm related
public static final UUID UUID_UNKNOWN_CHARACTERISTIC4 = UUID.fromString("00000004-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC5 = UUID.fromString("00000005-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC6 = UUID.fromString("00000006-0000-3512-2118-0009af100700");
public static final UUID UUID_UNKNOWN_CHARACTERISTIC7 = UUID.fromString("00000007-0000-3512-2118-0009af100700");

View File

@ -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<T extends AbstractBTLEDeviceSupport> extends AbstractBleProfile<T> {
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<T extends AbstractBTLEDeviceSupport> 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;
}
}

View File

@ -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;
@ -86,6 +87,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(MiBand2Support.class);
private final DeviceInfoProfile<MiBand2Support> deviceInfoProfile;
private final HeartRateProfile<MiBand2Support> heartRateProfile;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@ -119,6 +121,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
deviceInfoProfile = new DeviceInfoProfile<>(this);
addSupportedProfile(deviceInfoProfile);
heartRateProfile = new HeartRateProfile<MiBand2Support>(this);
addSupportedProfile(heartRateProfile);
LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext());
IntentFilter intentFilter = new IntentFilter();
@ -230,6 +234,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 +678,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.requestHeartRateMeasurement(builder);
// profile.resetEnergyExpended(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);
@ -1056,43 +1063,27 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
Calendar calendar = alarm.getAlarmCal();
int daysMask = 0;
if (alarm.getIndex() != 0 && alarm.isEnabled()) {
GB.toast(getContext(), "Only the first alarm is currently supported.", Toast.LENGTH_LONG, GB.WARN);
int maxAlarms = 5; // arbitrary at the moment...
if (alarm.getIndex() >= maxAlarms) {
if (alarm.isEnabled()) {
GB.toast(getContext(), "Only 5 alarms are currently supported.", Toast.LENGTH_LONG, GB.WARN);
}
return;
}
if (alarm.isEnabled()) {
if (alarm.getRepetition(Alarm.ALARM_MON)) {
daysMask |= 1;
}
if (alarm.getRepetition(Alarm.ALARM_TUE)) {
daysMask |= 2;
}
if (alarm.getRepetition(Alarm.ALARM_WED)) {
daysMask |= 4;
}
if (alarm.getRepetition(Alarm.ALARM_THU)) {
daysMask |= 8;
}
if (alarm.getRepetition(Alarm.ALARM_FRI)) {
daysMask |= 16;
}
if (alarm.getRepetition(Alarm.ALARM_SAT)) {
daysMask |= 32;
}
if (alarm.getRepetition(Alarm.ALARM_SUN)) {
daysMask |= 64;
}
daysMask = alarm.getRepetitionMask();
}
byte[] alarmMessage = new byte[] {
(byte) 0x2, // TODO what is this? 0x1 does not work
(byte) 128, // TODO: what is this?
(byte) 0x2, // TODO what is this?
(byte) (128 + alarm.getIndex()), // 128 is the base, alarm slot is added
(byte) calendar.get(Calendar.HOUR_OF_DAY),
(byte) calendar.get(Calendar.MINUTE),
(byte) daysMask,
};
builder.write(characteristic, alarmMessage);
// TODO: react on 0x10, 0x02, 0x01 on notification (success)
}
private void handleControlPointResult(byte[] value, int status) {

View File

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<changelog>
<release version="0.13.6" versioncode="68">
<change>Mi Band 2: Support multiple alarms (3 at the moment)</change>
<change>Mi Band 2: Fix for alarms not working when just one is enabled</change>
</release>
<release version="0.13.5" versioncode="67">
<change>Mi Band 2: Support setting one alarm</change>
<change>Pebble: Health compatibility for Firmware 4.2</change>