From 1e324acd6513493d6d28115ce5633e725c454d22 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sat, 11 Nov 2017 00:04:51 +0100 Subject: [PATCH] Mi Band 2/Bip/Cor: Whole day HR Measurement --- app/build.gradle | 2 +- .../gadgetbridge/devices/EventHandler.java | 2 ++ .../devices/miband/MiBand2Service.java | 2 ++ .../miband/MiBandPreferencesActivity.java | 9 ++++++ .../gadgetbridge/impl/GBDeviceService.java | 7 +++++ .../gadgetbridge/model/DeviceService.java | 2 ++ .../service/DeviceCommunicationService.java | 7 +++++ .../service/ServiceDeviceSupport.java | 10 ++++++- .../service/devices/hplus/HPlusSupport.java | 5 ++++ .../devices/jyou/TeclastH30Support.java | 5 ++++ .../devices/liveview/LiveviewSupport.java | 5 ++++ .../service/devices/miband/MiBandSupport.java | 5 ++++ .../devices/miband2/MiBand2Support.java | 29 +++++++++++++++++++ .../service/devices/no1f1/No1F1Support.java | 5 ++++ .../service/devices/pebble/PebbleSupport.java | 5 ++++ .../vibratissimo/VibratissimoSupport.java | 5 ++++ app/src/main/res/values/arrays.xml | 18 ++++++++++++ app/src/main/res/values/strings.xml | 7 +++++ app/src/main/res/xml/miband_preferences.xml | 10 ++++++- .../service/TestDeviceSupport.java | 5 ++++ 20 files changed, 142 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fd59447790..5f7f4dfac8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index 7d72f401e3..8d6e869393 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -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); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index 15825348e6..d18707577b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -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 { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index cb9337e349..bc222ccd5c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -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 diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index e637252080..f7c2e09a0a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -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) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 4cee593178..f9e9575b1d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -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"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 3fe997434a..1276b1a29b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -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); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index a1b7f67de7..de27c6037a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -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)) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index f84f205689..ebbc481cdc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -635,6 +635,11 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + @Override public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java index fbff9af617..dd523f9f37 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/jyou/TeclastH30Support.java @@ -429,6 +429,11 @@ public class TeclastH30Support extends AbstractBTLEDeviceSupport { } + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + @Override public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java index f12c9a0578..898a0b811c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewSupport.java @@ -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(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index 6bda8bc8e6..94839f37ac 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -442,6 +442,11 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } } + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + @Override public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { // not supported diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index a83ba843f2..37b866a9a8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -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 { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java index e11c758492..55b1a036cd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/no1f1/No1F1Support.java @@ -350,6 +350,11 @@ public class No1F1Support extends AbstractBTLEDeviceSupport { } + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + @Override public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java index 3bd1bde318..10b24e86a8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java @@ -132,6 +132,11 @@ public class PebbleSupport extends AbstractSerialDeviceSupport { } + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + @Override public synchronized PebbleIoThread getDeviceIOThread() { return (PebbleIoThread) super.getDeviceIOThread(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java index 3629fd19eb..17e02276a2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/vibratissimo/VibratissimoSupport.java @@ -253,6 +253,11 @@ public class VibratissimoSupport extends AbstractBTLEDeviceSupport { } + @Override + public void onSetHeartRateMeasurementInterval(int seconds) { + + } + @Override public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) { diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index f3b5ce6c5c..95a0bcb8e9 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -216,4 +216,22 @@ 2 + + @string/off + @string/interval_one_minute + @string/interval_five_minutes + @string/interval_ten_minutes + @string/interval_thirty_minutes + @string/interval_one_hour + + + + 0 + 60 + 300 + 600 + 1800 + 3600 + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f8ec299534..c9feac2942 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -268,6 +268,13 @@ Navigation Social network + Whole day HR measurement + once a minute + every 5 minutes + every 10 minutes + every 30 minutes + once an hour + Speed zones Total minutes Steps per minute diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index 3798c8f66b..56418ed233 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -98,7 +98,15 @@ android:key="mi_hr_sleep_detection" android:title="@string/miband_prefs_hr_sleep_detection" /> - + +