1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-03 17:02:13 +01:00

Mi Band 2/Bip/Cor: Whole day HR Measurement

This commit is contained in:
Andreas Shimokawa 2017-11-11 00:04:51 +01:00
parent 3b4628f87a
commit 1e324acd65
20 changed files with 142 additions and 3 deletions

View File

@ -18,7 +18,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_7
}
compileSdkVersion 25
buildToolsVersion '25.0.2'
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "nodomain.freeyourgadget.gadgetbridge"

View File

@ -83,6 +83,8 @@ public interface EventHandler {
void onEnableHeartRateSleepSupport(boolean enable);
void onSetHeartRateMeasurementInterval(int seconds);
void onAddCalendarEvent(CalendarEventSpec calendarEventSpec);
void onDeleteCalendarEvent(byte type, long id);

View File

@ -202,6 +202,8 @@ public class MiBand2Service {
public static final byte[] COMMAND_ENABLE_HR_SLEEP_MEASUREMENT = new byte[]{0x15, 0x00, 0x01};
public static final byte[] COMMAND_DISABLE_HR_SLEEP_MEASUREMENT = new byte[]{0x15, 0x00, 0x00};
public static final byte COMMAND_SET_PERIODIC_HR_MEASUREMENT_INTERVAL = 0x14;
public static final byte[] COMMAND_TEXT_NOTIFICATION = new byte[] {0x05, 0x01};
static {

View File

@ -84,6 +84,15 @@ public class MiBandPreferencesActivity extends AbstractSettingsActivity {
}
});
final Preference heartrateMeasurementInterval = findPreference("heartrate_measurement_interval");
heartrateMeasurementInterval.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
GBApplication.deviceService().onSetHeartRateMeasurementInterval(Integer.parseInt((String) newVal));
return true;
}
});
final Preference goalNotification = findPreference(PREF_MI2_GOAL_NOTIFICATION);
goalNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override

View File

@ -322,6 +322,13 @@ public class GBDeviceService implements DeviceService {
invokeService(intent);
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
Intent intent = createIntent().setAction(ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL)
.putExtra(EXTRA_INTERVAL_SECONDS, seconds);
invokeService(intent);
}
@Override
public void onEnableRealtimeHeartRateMeasurement(boolean enable) {
Intent intent = createIntent().setAction(ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT)

View File

@ -58,6 +58,7 @@ public interface DeviceService extends EventHandler {
String ACTION_REALTIME_SAMPLES = PREFIX + ".action.realtime_samples";
String ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT = PREFIX + ".action.realtime_hr_measurement";
String ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT = PREFIX + ".action.enable_heartrate_sleep_support";
String ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL = PREFIX + ".action.set_heartrate_measurement_intervarl";
String ACTION_HEARTRATE_MEASUREMENT = PREFIX + ".action.hr_measurement";
String ACTION_ADD_CALENDAREVENT = PREFIX + ".action.add_calendarevent";
String ACTION_DELETE_CALENDAREVENT = PREFIX + ".action.delete_calendarevent";
@ -101,6 +102,7 @@ public interface DeviceService extends EventHandler {
String EXTRA_ALARMS = "alarms";
String EXTRA_CONNECT_FIRST_TIME = "connect_first_time";
String EXTRA_BOOLEAN_ENABLE = "enable_realtime_steps";
String EXTRA_INTERVAL_SECONDS = "interval_seconds";
String EXTRA_WEATHER_TIMESTAMP = "weather_timestamp";
String EXTRA_WEATHER_LOCATION = "weather_location";

View File

@ -100,6 +100,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SE
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SETTIME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_ALARMS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_CONSTANT_VIBRATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_STARTAPP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_TEST_NEW_FUNCTION;
@ -124,6 +125,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CAN
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CONFIG;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CONNECT_FIRST_TIME;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_FIND_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_INTERVAL_SECONDS;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ALBUM;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ARTIST;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_DURATION;
@ -518,6 +520,11 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
mDeviceSupport.onEnableHeartRateSleepSupport(enable);
break;
}
case ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL: {
Integer seconds = intent.getIntExtra(EXTRA_INTERVAL_SECONDS, 0);
mDeviceSupport.onSetHeartRateMeasurementInterval(seconds);
break;
}
case ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT: {
boolean enable = intent.getBooleanExtra(EXTRA_BOOLEAN_ENABLE, false);
mDeviceSupport.onEnableRealtimeHeartRateMeasurement(enable);

View File

@ -313,12 +313,20 @@ public class ServiceDeviceSupport implements DeviceSupport {
@Override
public void onEnableHeartRateSleepSupport(boolean enable) {
if (checkBusy("enable heartrate sleep support: " + enable)) {
if (checkBusy("enable heart rate sleep support: " + enable)) {
return;
}
delegate.onEnableHeartRateSleepSupport(enable);
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
if (checkBusy("set heart rate measurement interval: " + seconds + "s")) {
return;
}
delegate.onSetHeartRateMeasurementInterval(seconds);
}
@Override
public void onEnableRealtimeHeartRateMeasurement(boolean enable) {
if (checkBusy("enable realtime heart rate measurement: " + enable)) {

View File

@ -635,6 +635,11 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {

View File

@ -429,6 +429,11 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {

View File

@ -74,6 +74,11 @@ public class LiveviewSupport extends AbstractSerialDeviceSupport {
//nothing to do ATM
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public synchronized LiveviewIoThread getDeviceIOThread() {
return (LiveviewIoThread) super.getDeviceIOThread();

View File

@ -442,6 +442,11 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
}
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
// not supported

View File

@ -470,6 +470,20 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
}
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
try {
int minuteInterval = seconds / 60;
minuteInterval = Math.min(minuteInterval, 120);
minuteInterval = Math.max(0,minuteInterval);
TransactionBuilder builder = performInitialized("set heart rate interval to: " + minuteInterval + " minutes");
setHeartrateMeasurementInterval(builder, minuteInterval);
builder.queue(getQueue());
} catch (IOException e) {
GB.toast(getContext(), "Error toggling heart rate sleep support: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR);
}
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
// not supported
@ -501,6 +515,16 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
return this;
}
private MiBand2Support setHeartrateMeasurementInterval(TransactionBuilder builder, int minutes) {
if (characteristicHRControlPoint != null) {
builder.notify(characteristicHRControlPoint, true);
LOG.info("Setting heart rate measurement interval to " + minutes + " minutes");
builder.write(characteristicHRControlPoint, new byte[]{MiBand2Service.COMMAND_SET_PERIODIC_HR_MEASUREMENT_INTERVAL, (byte) minutes});
builder.notify(characteristicHRControlPoint, false); // TODO: this should actually be in some kind of finally-block in the queue. It should also be sent asynchronously after the notifications have completely arrived and processed.
}
return this;
}
private void performDefaultNotification(String task, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) {
try {
TransactionBuilder builder = performInitialized(task);
@ -1540,6 +1564,11 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
setGoalNotification(builder);
setInactivityWarnings(builder);
setHeartrateSleepSupport(builder);
setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval());
}
private int getHeartRateMeasurementInterval() {
return GBApplication.getPrefs().getInt("heartrate_measurement_interval", 0) / 60;
}
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {

View File

@ -350,6 +350,11 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {

View File

@ -132,6 +132,11 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public synchronized PebbleIoThread getDeviceIOThread() {
return (PebbleIoThread) super.getDeviceIOThread();

View File

@ -253,6 +253,11 @@ public class VibratissimoSupport extends AbstractBTLEDeviceSupport {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {

View File

@ -216,4 +216,22 @@
<item>2</item>
</string-array>
<string-array name="prefs_heartrate_measurement_interval">
<item name="0">@string/off</item>
<item name="60">@string/interval_one_minute</item>
<item name="300">@string/interval_five_minutes</item>
<item name="600">@string/interval_ten_minutes</item>
<item name="1800">@string/interval_thirty_minutes</item>
<item name="3600">@string/interval_one_hour</item>
</string-array>
<string-array name="prefs_heartrate_measurement_interval_values">
<item>0</item>
<item>60</item>
<item>300</item>
<item>600</item>
<item>1800</item>
<item>3600</item>
</string-array>
</resources>

View File

@ -268,6 +268,13 @@
<string name="pref_screen_notification_profile_generic_navigation">Navigation</string>
<string name="pref_screen_notification_profile_generic_social">Social network</string>
<string name="prefs_title_heartrate_measurement_interval">Whole day HR measurement</string>
<string name="interval_one_minute">once a minute</string>
<string name="interval_five_minutes">every 5 minutes</string>
<string name="interval_ten_minutes">every 10 minutes</string>
<string name="interval_thirty_minutes">every 30 minutes</string>
<string name="interval_one_hour">once an hour</string>
<string name="stats_title">Speed zones</string>
<string name="stats_x_axis_label">Total minutes</string>
<string name="stats_y_axis_label">Steps per minute</string>

View File

@ -98,7 +98,15 @@
android:key="mi_hr_sleep_detection"
android:title="@string/miband_prefs_hr_sleep_detection" />
<EditTextPreference
<ListPreference
android:defaultValue="0"
android:entries="@array/prefs_heartrate_measurement_interval"
android:entryValues="@array/prefs_heartrate_measurement_interval_values"
android:key="heartrate_measurement_interval"
android:summary="%s"
android:title="@string/prefs_title_heartrate_measurement_interval" />
<EditTextPreference
android:defaultValue="0"
android:inputType="numberSigned"
android:key="mi_device_time_offset_hours"

View File

@ -154,6 +154,11 @@ class TestDeviceSupport extends AbstractDeviceSupport {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {