1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-01 22:43:00 +01:00

Add watch power mode and DND

This commit is contained in:
mamutcho 2019-11-10 23:15:13 +02:00
parent 3a2b718f09
commit 24439008ab
9 changed files with 384 additions and 77 deletions

View File

@ -91,7 +91,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
Prefs prefs = GBApplication.getPrefs(); Prefs prefs = GBApplication.getPrefs();
Preference pref = findPreference("notifications_generic"); Preference pref = findPreference("notifications_generic");
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"); Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
@ -211,13 +210,22 @@ public class SettingsActivity extends AbstractSettingsActivity {
}); });
pref = findPreference("watchxplus_button_BP_calibration"); pref = findPreference("wxp_button_BP_calibration");
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
preference.setSummary("Calibrating, please wait... (if no result after 15s. re-run)");
GBApplication.deviceService().onSendConfiguration("BP_CAL");
return true;
}
});
pref = findPreference("wxp_power_mode");
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override @Override
public boolean onPreferenceChange(Preference preference, Object newVal) { public boolean onPreferenceChange(Preference preference, Object newVal) {
LOG.info(" uhaaaa "); LOG.info(" uhaaaa ");
preference.setSummary("Calibrating, please wait... (if no result after 15s. re-run)"); GBApplication.deviceService().onSendConfiguration("WXP_POWER_MODE");
GBApplication.deviceService().onSendConfiguration("BP_CAL");
return true; return true;
} }
}); });

View File

@ -43,7 +43,9 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final String PREF_SHAKE_REJECT = "watchxplus_shake_reject"; public static final String PREF_SHAKE_REJECT = "watchxplus_shake_reject";
public static final String PREF_BP_CAL_LOW = "pref_wxp_bp_calibration_low"; public static final String PREF_BP_CAL_LOW = "pref_wxp_bp_calibration_low";
public static final String PREF_BP_CAL_HIGH = "pref_wxp_bp_calibration_high"; public static final String PREF_BP_CAL_HIGH = "pref_wxp_bp_calibration_high";
public static final String PREF_DO_NOT_DISTURB = "do_not_disturb_no_auto";
public static final String PREF_DO_NOT_DISTURB_START = "do_not_disturb_no_auto_start";
public static final String PREF_DO_NOT_DISTURB_END = "do_not_disturb_no_auto_end";
// time format constants // time format constants
public static final byte ARG_SET_TIMEMODE_24H = 0x00; public static final byte ARG_SET_TIMEMODE_24H = 0x00;
@ -66,7 +68,10 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final byte[] CMD_NOTIFICATION_CANCEL = new byte[]{0x03, 0x04}; public static final byte[] CMD_NOTIFICATION_CANCEL = new byte[]{0x03, 0x04};
public static final byte[] CMD_NOTIFICATION_SETTINGS = new byte[]{0x03, 0x02}; public static final byte[] CMD_NOTIFICATION_SETTINGS = new byte[]{0x03, 0x02};
public static final byte[] CMD_DO_NOT_DISTURB_SETTINGS = new byte[]{0x03, 0x61}; public static final byte[] CMD_DO_NOT_DISTURB_SETTINGS = new byte[]{0x03, 0x61};
public static final byte[] CMD_POWER_MODE = new byte[]{0x03, -0x7F}; //bArr[8] - 0 normal, 1 poser save, 2 green public static final byte[] CMD_POWER_MODE = new byte[]{0x03, -0x7F};
public static final byte[] CMD_SET_QUITE_HOURS_TIME = new byte[]{0x03, 0x62};
public static final byte[] CMD_SET_QUITE_HOURS_SWITCH = new byte[]{0x03, 0x61};
public static final byte[] CMD_SET_PERSONAL_INFO = new byte[]{0x01, 0x0E};
public static final byte[] CMD_FITNESS_GOAL_SETTINGS = new byte[]{0x10, 0x02}; public static final byte[] CMD_FITNESS_GOAL_SETTINGS = new byte[]{0x10, 0x02};
public static final byte[] CMD_DAY_STEPS_INFO = new byte[]{0x10, 0x03}; public static final byte[] CMD_DAY_STEPS_INFO = new byte[]{0x10, 0x03};
@ -81,6 +86,8 @@ public final class WatchXPlusConstants extends LenovoWatchConstants {
public static final byte[] RESP_IS_BP_CALIBRATED = new byte[]{0x08, 0x05, 0x0B}; public static final byte[] RESP_IS_BP_CALIBRATED = new byte[]{0x08, 0x05, 0x0B};
public static final byte[] RESP_BUTTON_WHILE_RING = new byte[]{0x04, 0x03, 0x03}; public static final byte[] RESP_BUTTON_WHILE_RING = new byte[]{0x04, 0x03, 0x03};
public static final byte[] RESP_BP_CALIBRATION = new byte[]{0x08, 0x05, 0x0C}; public static final byte[] RESP_BP_CALIBRATION = new byte[]{0x08, 0x05, 0x0C};
public static final byte[] RESP_SET_PERSONAL_INFO = new byte[]{0x08, 0x01, 0x0E};
public static final byte[] RESP_GOAL_AIM_STATUS = new byte[]{0x08, 0x10, 0x02};
public static final byte[] RESP_AUTHORIZATION_TASK = new byte[]{0x01, 0x01, 0x05}; public static final byte[] RESP_AUTHORIZATION_TASK = new byte[]{0x01, 0x01, 0x05};
public static final byte[] RESP_DAY_STEPS_INDICATOR = new byte[]{0x08, 0x10, 0x03}; public static final byte[] RESP_DAY_STEPS_INDICATOR = new byte[]{0x08, 0x10, 0x03};

View File

@ -12,6 +12,12 @@ import android.os.ParcelUuid;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -34,8 +40,9 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext; import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
private static final Logger LOG = LoggerFactory.getLogger(WatchXPlusDeviceSupport.class);
public static final int FindPhone_ON = -1; public static final int FindPhone_ON = -1;
public static final int FindPhone_OFF = 0; public static final int FindPhone_OFF = 0;
public static boolean isBPCalibrated = false; public static boolean isBPCalibrated = false;
@ -163,7 +170,8 @@ public class WatchXPlusDeviceCoordinator extends AbstractDeviceCoordinator {
R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_liftwrist_display,
R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_disconnectnotification,
R.xml.devicesettings_find_phone, R.xml.devicesettings_find_phone,
R.xml.devicesettings_timeformat R.xml.devicesettings_timeformat,
R.xml.devicesettings_donotdisturb_no_auto
}; };
} }
@ -224,6 +232,34 @@ Prefs from device settings on main page
} }
} }
/**
* @param startOut out Only hour/minute are used.
* @param endOut out Only hour/minute are used.
* @return True if quite hours are enabled.
*/
public static boolean getQuiteHours(SharedPreferences sharedPrefs, Calendar startOut, Calendar endOut) {
String doNotDisturb = sharedPrefs.getString(WatchXPlusConstants.PREF_DO_NOT_DISTURB, getContext().getString(R.string.p_off));
if (doNotDisturb.equals(getContext().getString(R.string.p_off))) {
LOG.info(" DND is disabled ");
return false;
} else {
String start = sharedPrefs.getString(WatchXPlusConstants.PREF_DO_NOT_DISTURB_START, "00:00");
String end = sharedPrefs.getString(WatchXPlusConstants.PREF_DO_NOT_DISTURB_END, "00:00");
DateFormat df = new SimpleDateFormat("HH:mm");
try {
startOut.setTime(df.parse(start));
endOut.setTime(df.parse(end));
return true;
} catch (Exception e) {
return false;
}
}
}
/* /*
Values from device specific settings page Values from device specific settings page
*/ */

View File

@ -1,27 +1,19 @@
NEDD TO BE DONE NEDD TO BE DONE
Watch settings Watch settings
- Set watch modes (energy saving):
- Normal -> the watch work normally
- Power-saving mode -> the app turn off the bluetooth on the watch
- Trad-watch mode -> the watch only works as an analog one
- Set watch language (currently forced to English) - Set watch language (currently forced to English)
- Set watch units (metric/imperial) - Set watch units (metric/imperial)
- Implement send User details to watch - Implement temperature alarm on watch
- Age, height, gender, etc.
- Implement Do not disturb (on, off, scheduled)
- Implement themperature alarm on watch
- switch, lowTemp, highTemp - switch, lowTemp, highTemp
- Implement continious blood pressure measurement (on, off, scheduled) - Implement continious blood pressure measurement (on, off, scheduled)
- implement long sit reminder - Implement long sit reminder
Add feature to initiate button press event on watch Add feature to initiate button press event on watch
- Send command to watch - Send command to watch
- Get triger on button press - Get trigger on button press
Schedulers: Schedulers:
- Screen on scheduler (inApp, not supported by watch) - Screen on scheduler (inApp, not supported by watch)
- Disconnect reminder scheduler (inApp, not supported by watch) - Disconnect reminder scheduler (inApp, not supported by watch)
- Do not disturb (supported by watch)
- Continious blood pressure measurement (supported by watch) - Continious blood pressure measurement (supported by watch)
Refine send weather to watch Refine send weather to watch
@ -32,51 +24,56 @@ NEDD TO BE DONE
Measurements Measurements
- Blood pressure mesurement - Blood pressure mesurement
- Add blood pressure calibration (view)
- Add blood pressure calibration function
- Show blood pressure measurement (view) - Show blood pressure measurement (view)
- Implement heart rate measurement - Implement heart rate measurement
- Implement themperature measurement - Implement temperature measurement
- Implement UV index measurement - Implement UV index measurement
WORK PROGRESS WORK PROGRESS
Send notification to watch Send notification to watch
- on incomming call - On incoming call
- add function to cancel notification on watch (04.11.2019) - add function to cancel notification on watch (04.11.2019)
- cancel notification on change phone state (end call, reject call etc.) (06.11.2019) - cancel notification on change phone state (end call, reject call etc.) (06.11.2019)
- settings for repeat notification [0-10 times] (05.11.2019) - settings for repeat notification [0-10 times] (05.11.2019)
- settings for continious notification while phone ring [on, off] (06.11.2019) - settings for continious notification while phone ring [on, off] (06.11.2019)
- settings for send once notification for missed call [on, off] (06.11.2019) - settings for send once notification for missed call [on, off] (06.11.2019)
- on text message, or other application - On text message, or other application
- on triger phone alarm (05.11.2019) - On triger phone alarm (05.11.2019)
Call handling Call handling
- setting for ignore/reject call with watch button [on->reject call, off->ignore call] (06.11.2019) - Setting for ignore/reject call with watch button [on->reject call, off->ignore call] (06.11.2019)
- setting for ignore/reject call with shake device - duplicates button action [on, off] (06.11.2019) - Setting for ignore/reject call with shake device - duplicates button action [on, off] (06.11.2019)
- on watch - show small phone icon near bluetooth icon when there are missed call (06.11.2019) - On watch - show small phone icon near bluetooth icon when there are missed call (06.11.2019)
Calibrations Calibrations
- time calibration - Time calibration
* send current date/time to watch * send current date/time to watch
- set watch alarms - Set watch alarms
- altitude calibration [altitude (meters)] (04.11.2019) - Altitude calibration [altitude (meters)] (04.11.2019)
* it's used in Climb activity * it's used in Climb activity
- status of blood pressure calibration (06.11.2019) - Status of blood pressure calibration (06.11.2019)
* it's used in blood pressure measurement * it's used in blood pressure measurement
- Blood pressure calibration (09.11.2019) (TODO fix button initiating calibration)
Device settings Device settings
- lift wrist to screen on [on, off,TODO scheduled] (02.11.2019) - Lift wrist to screen on [on, off,TODO scheduled] (02.11.2019)
- change time format 12/24h (02.11.2019) - Change time format 12/24h (02.11.2019)
- disconnect reminder [on, off,TODO scheduled] (02.11.2019) - Disconnect reminder [on, off,TODO scheduled] (02.11.2019)
- find my phone [on, off, ring duration] (02.11.2019) - Find my phone [on, off, ring duration] (02.11.2019)
- Set watch modes (energy saving) (10.11.2019) (Need testing)
- Normal -> the watch work normally
- Power-saving mode -> the app turn off the bluetooth on the watch
- Trad-watch mode -> the watch only works as an analog one
- Do not disturb [on, off, scheduled] (10.11.2019) (need reconnect to apply)
- Send User details to watch [height, weight, age, gender] (10.11.2019) (need more testing)
Activity data Activity data
- get steps per day - get steps per day
- get heart reate measurements - get heart reate measurements
- get sleep data - get sleep data
- set user goal for steps (TODO set user details) - set user goal for steps
Changed in app device icon (02.11.2019) Changed in app device icon (02.11.2019)
Get blood pressure measurement result (work only if blood pressure is calibrated) Get blood pressure measurement result (work only if blood pressure is calibrated)

View File

@ -26,18 +26,12 @@ import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.IntRange; import androidx.annotation.IntRange;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.snackbar.Snackbar;
import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -276,15 +270,6 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
return this; return this;
} }
private WatchXPlusDeviceSupport enableDoNotDisturb(TransactionBuilder builder, boolean active) {
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_DO_NOT_DISTURB_SETTINGS,
WatchXPlusConstants.WRITE_VALUE,
new byte[]{(byte) (active ? 0x01 : 0x00)}));
return this;
}
private void enableCalibration(boolean enable) { private void enableCalibration(boolean enable) {
try { try {
TransactionBuilder builder = performInitialized("enableCalibration"); TransactionBuilder builder = performInitialized("enableCalibration");
@ -399,21 +384,10 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
return this; return this;
} }
private WatchXPlusDeviceSupport setFitnessGoal(TransactionBuilder builder) {
int fitnessGoal = new ActivityUser().getStepsGoal();
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_FITNESS_GOAL_SETTINGS,
WatchXPlusConstants.WRITE_VALUE,
Conversion.toByteArr16(fitnessGoal)));
return this;
}
public WatchXPlusDeviceSupport initialize(TransactionBuilder builder) { public WatchXPlusDeviceSupport initialize(TransactionBuilder builder) {
getFirmwareVersion(builder) getFirmwareVersion(builder)
.getBatteryState(builder) .getBatteryState(builder)
.enableNotificationChannels(builder) .enableNotificationChannels(builder)
.enableDoNotDisturb(builder, false)
.setFitnessGoal(builder) .setFitnessGoal(builder)
.getBloodPressureCalibrationStatus(builder) .getBloodPressureCalibrationStatus(builder)
.syncPreferences(builder); .syncPreferences(builder);
@ -574,8 +548,43 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
} }
} }
private WatchXPlusDeviceSupport setFitnessGoal(TransactionBuilder builder) {
int fitnessGoal = new ActivityUser().getStepsGoal();
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_FITNESS_GOAL_SETTINGS,
WatchXPlusConstants.WRITE_VALUE,
Conversion.toByteArr16(fitnessGoal)));
return this;
}
// set personal info
private WatchXPlusDeviceSupport setPersonalInformation(TransactionBuilder builder, int height, int weight, int age, int gender) {
LOG.warn(" Setting Personal Information... height:"+height+" weight:"+weight+" age:"+age+" gender:"+gender);
byte[] command = WatchXPlusConstants.CMD_SET_PERSONAL_INFO;
byte[] bArr = new byte[4];
bArr[0] = (byte) height; // byte[08]
bArr[1] = (byte) weight; // byte[09]
bArr[2] = (byte) age; // byte[10]
bArr[3] = (byte) gender; // byte[11]
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(command,
WatchXPlusConstants.WRITE_VALUE,
bArr));
return this;
}
// handle get/set personal info
// for test purposes only
private void handlePersonalInfo(byte[] value) {
int height = Conversion.fromByteArr16(value[8]);
int weight = Conversion.fromByteArr16(value[9]);
int age = Conversion.fromByteArr16(value[10]);
int gender = Conversion.fromByteArr16(value[11]);
LOG.info(" Personal info - height:" + height + ", weight:" + weight + ", age:" + age + ", gender:" + gender);
}
@Override @Override
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) { public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
@ -648,7 +657,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
@Override @Override
public void onReset(int flags) { public void onReset(int flags) {
// testNewCommands();
} }
@Override @Override
@ -701,6 +710,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress()); SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress());
try { try {
builder = performInitialized("sendConfig: " + config); builder = performInitialized("sendConfig: " + config);
LOG.info(" config changed:" + config);
switch (config) { switch (config) {
case ActivityUser.PREF_USER_STEPS_GOAL: case ActivityUser.PREF_USER_STEPS_GOAL:
setFitnessGoal(builder); setFitnessGoal(builder);
@ -716,9 +726,18 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT: case DeviceSettingsPreferenceConst.PREF_TIMEFORMAT:
setTimeFormat(builder, sharedPreferences); setTimeFormat(builder, sharedPreferences);
break; break;
case WatchXPlusConstants.PREF_DO_NOT_DISTURB:
case WatchXPlusConstants.PREF_DO_NOT_DISTURB_START:
case WatchXPlusConstants.PREF_DO_NOT_DISTURB_END:
LOG.info(" bravo ");
setQuiteHours(builder, sharedPreferences);
break;
case "BP_CAL": case "BP_CAL":
sendBloodPressureCalibration(); sendBloodPressureCalibration();
break; break;
case "WXP_POWER_MODE":
setPowerMode(config);
break;
} }
builder.queue(getQueue()); builder.queue(getQueue());
} catch (IOException e) { } catch (IOException e) {
@ -736,6 +755,71 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
requestBloodPressureMeasurement(); requestBloodPressureMeasurement();
} }
// set do not disturb time
private WatchXPlusDeviceSupport setQuiteHours(TransactionBuilder tbuilder, boolean enable, int hourStart, int minuteStart, int hourEnd, int minuteEnd) {
LOG.warn(" Setting DND time... Hs:"+hourStart+" Ms:"+minuteStart+" He:"+hourEnd+" Me:"+minuteEnd);
byte[] command = WatchXPlusConstants.CMD_SET_QUITE_HOURS_TIME;
byte[] bArr = new byte[4];
bArr[0] = (byte) hourStart; // byte[08]
bArr[1] = (byte) minuteStart; // byte[09]
bArr[2] = (byte) hourEnd; // byte[10]
bArr[3] = (byte) minuteEnd; // byte[11]
tbuilder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_SET_QUITE_HOURS_TIME,
WatchXPlusConstants.WRITE_VALUE,
bArr));
setQuiteHoursSwitch(tbuilder, enable);
return this;
}
// set do not disturb switch
private WatchXPlusDeviceSupport setQuiteHoursSwitch(TransactionBuilder tbuilder, boolean enable) {
LOG.warn("Setting DND switch to" + enable);
tbuilder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_SET_QUITE_HOURS_SWITCH,
WatchXPlusConstants.WRITE_VALUE,
new byte[]{(byte) (enable ? 0x01 : 0x00)}));
return this;
}
private WatchXPlusDeviceSupport setQuiteHours(TransactionBuilder builder, SharedPreferences sharedPreferences) {
Calendar start = new GregorianCalendar();
Calendar end = new GregorianCalendar();
boolean enable = WatchXPlusDeviceCoordinator.getQuiteHours(sharedPreferences, start, end);
if (enable) {
return this.setQuiteHours(builder, enable,
start.get(Calendar.HOUR_OF_DAY), start.get(Calendar.MINUTE),
end.get(Calendar.HOUR_OF_DAY), end.get(Calendar.MINUTE));
} else {
LOG.info(" Quiet hours are disabled");
return this.setQuiteHoursSwitch(builder, enable);
}
}
// set watch power mode
private WatchXPlusDeviceSupport setPowerMode(String config) {
int settingRead = prefs.getInt("wxp_power_mode", 0);
byte[] bArr = new byte[1];
if (settingRead == 0) bArr[0] = 0x00;
if (settingRead == 1) bArr[0] = 0x01;
if (settingRead == 2) bArr[0] = 0x02;
LOG.info(" setting: " + config + " mode: " + bArr[0]);
try {
TransactionBuilder builder = performInitialized("setPowerMode");
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(WatchXPlusConstants.CMD_POWER_MODE,
WatchXPlusConstants.TASK,
bArr));
builder.queue(getQueue());
} catch (IOException e) {
LOG.warn("Unable to set power mode", e);
}
return this;
}
// check status of blood pressure calibration // check status of blood pressure calibration
private WatchXPlusDeviceSupport getBloodPressureCalibrationStatus(TransactionBuilder builder) { private WatchXPlusDeviceSupport getBloodPressureCalibrationStatus(TransactionBuilder builder) {
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE), builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
@ -771,7 +855,8 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
buildCommand(command, buildCommand(command,
WatchXPlusConstants.TASK, WatchXPlusConstants.TASK,
bArr)); bArr));
builder.queue(getQueue()); } catch (IOException e) { builder.queue(getQueue());
} catch (IOException e) {
LOG.warn("Unable to send BP Calibration", e); LOG.warn("Unable to send BP Calibration", e);
} }
return this; return this;
@ -820,27 +905,27 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
} }
/*
// not working!!! // not working!!!
private void requestHeartRateMeasurement() { private void testNewCommands() {
try { try {
TransactionBuilder builder = performInitialized("hrMeasure"); TransactionBuilder builder = performInitialized("test");
byte[] command = new byte[]{0x05, 0x0B}; int first = prefs.getInt("wxp_newcmd_first", 0);
int second = prefs.getInt("wxp_newcmd_second", 0);
byte[] command = new byte[]{(byte) first, (byte) second};
LOG.info("testing new command " + command);
builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE), builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
buildCommand(command, buildCommand(command,
WatchXPlusConstants.READ_VALUE)); WatchXPlusConstants.READ_VALUE));
// builder.write(getCharacteristic(WatchXPlusConstants.UUID_CHARACTERISTIC_WRITE),
// buildCommand(command,
// WatchXPlusConstants.TASK, new byte[]{0x01}));
builder.queue(getQueue()); builder.queue(getQueue());
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Unable to request HR Measure", e); LOG.warn("Unable to request HR Measure", e);
} }
} }
*/
@Override @Override
public void onSendWeather(WeatherSpec weatherSpec) { public void onSendWeather(WeatherSpec weatherSpec) {
@ -878,12 +963,16 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
handleFirmwareInfo(value); handleFirmwareInfo(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_SHAKE_SWITCH, 5)) { } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_SHAKE_SWITCH, 5)) {
handleShakeState(value); handleShakeState(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_SET_PERSONAL_INFO, 5)) {
handlePersonalInfo(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BUTTON_WHILE_RING, 5)) { } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BUTTON_WHILE_RING, 5)) {
handleButtonWhenRing(value); handleButtonWhenRing(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_DISCONNECT_REMIND, 5)) { } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_DISCONNECT_REMIND, 5)) {
handleDisconnectReminderState(value); handleDisconnectReminderState(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BATTERY_INFO, 5)) { } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_BATTERY_INFO, 5)) {
handleBatteryState(value); handleBatteryState(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_GOAL_AIM_STATUS, 5)) {
handleSportAimStatus(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_TIME_SETTINGS, 5)) { } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_TIME_SETTINGS, 5)) {
handleTime(value); handleTime(value);
} else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_IS_BP_CALIBRATED, 5)) { } else if (ArrayUtils.equals(value, WatchXPlusConstants.RESP_IS_BP_CALIBRATED, 5)) {
@ -1214,6 +1303,11 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
return result; return result;
} }
private void handleSportAimStatus(byte[] value) {
int stepsAim = Conversion.fromByteArr16(value[8], value[9]);
LOG.debug(" Received goal stepsAim: " + stepsAim);
}
private void handleStepsInfo(byte[] value) { private void handleStepsInfo(byte[] value) {
int steps = Conversion.fromByteArr16(value[8], value[9]); int steps = Conversion.fromByteArr16(value[8], value[9]);
LOG.debug(" Received steps count: " + steps); LOG.debug(" Received steps count: " + steps);
@ -1395,9 +1489,13 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
private void syncPreferences(TransactionBuilder transaction) { private void syncPreferences(TransactionBuilder transaction) {
SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress()); SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress());
this.setHeadsUpScreen(transaction, sharedPreferences); // lift wirst to screen on this.setHeadsUpScreen(transaction, sharedPreferences); // lift wirst to screen on
this.setQuiteHours(transaction, sharedPreferences); // DND
this.setDisconnectReminder(transaction, sharedPreferences); // disconnect reminder this.setDisconnectReminder(transaction, sharedPreferences); // disconnect reminder
this.setTimeFormat(transaction, sharedPreferences); // set time mode 12/24h this.setTimeFormat(transaction, sharedPreferences); // set time mode 12/24h
this.setAltitude(transaction); // set altitude calibration this.setAltitude(transaction); // set altitude calibration
ActivityUser activityUser = new ActivityUser();
this.setPersonalInformation(transaction, activityUser.getHeightCm(), activityUser.getWeightKg(),
activityUser.getAge(),activityUser.getGender());
} }
private Handler mFindPhoneHandler = new Handler(); private Handler mFindPhoneHandler = new Handler();

View File

@ -284,7 +284,7 @@
<string name="title_activity_watch9_pairing">Watch 9 свързване</string> <string name="title_activity_watch9_pairing">Watch 9 свързване</string>
<string name="title_activity_watch9_calibration">Watch 9 сверяване</string> <string name="title_activity_watch9_calibration">Watch 9 сверяване</string>
<string name="title_activity_watchXplus_calibration">WatchX Plus сверяване</string> <string name="title_activity_watchXplus_calibration">WatchX Plus сверяване</string>
<string name="pref_wxp_title_unit_system">Edinici</string> <string name="pref_wxp_title_unit_system">Единици</string>
<string name="pref_wxp_title_timeformat">Формат на часа</string> <string name="pref_wxp_title_timeformat">Формат на часа</string>
<string name="pref_wxp_title_altitude">Калибриране на височина</string> <string name="pref_wxp_title_altitude">Калибриране на височина</string>
<string name="pref_wxp_title_repeat_on_call">Повтори известия за звънене</string> <string name="pref_wxp_title_repeat_on_call">Повтори известия за звънене</string>
@ -466,4 +466,120 @@
<string name="live_activity_start_your_activity">Стартирайте активност</string> <string name="live_activity_start_your_activity">Стартирайте активност</string>
<string name="title_activity_device_specific_settings">Специфични настройки за устройството</string> <string name="title_activity_device_specific_settings">Специфични настройки за устройството</string>
<string name="average">Средно: %1$s</string> <string name="average">Средно: %1$s</string>
<string name="Cancel">Отказ</string>
<string name="Delete">Изтрий</string>
<string name="abstract_chart_fragment_kind_deep_sleep">Дълбок сън</string>
<string name="abstract_chart_fragment_kind_light_sleep">Лек сън</string>
<string name="abstract_chart_fragment_kind_not_worn">Не е носен</string>
<string name="abstract_chart_fragment_kind_activity">Активност</string>
<string name="_pebble_watch_reply">Отговори</string>
<string name="action_db_management">Управление на базата</string>
<string name="activity_DB_empty_button">Изчисти БД</string>
<string name="activity_DB_import_button">Импорт БД</string>
<string name="activity_DB_delete_legacy_button">Изтрий стара БД</string>
<string name="activity_DB_ExportButton">Експорт на БД</string>
<string name="activity_DB_test_export_message">Експортиране на БД...</string>
<string name="activity_DB_test_export_button">Стартирай авто експортиране</string>
<string name="activity_db_management_autoexport_explanation">Локацията за експорт на БД е:</string>
<string name="activity_db_management_autoexport_label">АвтоЕкспорт</string>
<string name="activity_db_management_empty_DB">ИзпразниБД</string>
<string name="activity_db_management_empty_db_warning">Внимание! Ако натиснете този бутон БД ще се изтрие.</string>
<string name="activity_db_management_exportimport_label">Експорт и Импорт</string>
<string name="activity_prefs_sleep_duration">Време за сън в часове</string>
<string name="activity_summaries">Активности</string>
<string name="activity_type_activity">Активност</string>
<string name="activity_type_biking">Колоездене</string>
<string name="activity_type_deep_sleep">Дълбок сън</string>
<string name="activity_type_light_sleep">Лек сън</string>
<string name="activity_type_exercise">Упражнение</string>
<string name="activity_type_not_measured">Не е измерено</string>
<string name="activity_type_not_worn">Не е носено</string>
<string name="activity_type_running">Бягане</string>
<string name="activity_type_swimming">Плуване</string>
<string name="activity_type_unknown">Неизвестна активност</string>
<string name="activity_type_walking">Ходене</string>
<string name="appwidget_not_connected">Не е свързан, алармата не е настроена.</string>
<string name="appwidget_setting_alarm">Аларма за %1$02d:%2$02d</string>
<string name="automatic">Автоматично</string>
<string name="authenticating">Удостоверяване</string>
<string name="authentication_required">Изисква удостоверяване</string>
<string name="charts_legend_heartrate">Сърдечна честота</string>
<string name="choose_auto_export_location">Избери локация за експорт</string>
<string name="dateformat_time">Час</string>
<string name="dbmanagementactivity_overwrite">Замени</string>
<string name="device_fw">Firmware версия: %1$s</string>
<string name="device_hw">Hardware версия: %1$s</string>
<string name="device_not_connected">Не е свързан.</string>
<string name="devicetype_unknown">Неизвестно устройство</string>
<string name="discovery_attempting_to_pair">Опит за свързване с %1$s</string>
<string name="discovery_dont_pair">Не се свързвай</string>
<string name="discovery_enable_bluetooth">Включи bluetooth за намиране на устройства.</string>
<string name="discovery_pair_title">Свързване с %1$s?</string>
<string name="discovery_trying_to_connect_to">Опит за свързване с: %1$s</string>
<string name="discovery_yes_pair">Свържи</string>
<string name="filter_mode_none">Не филтрирай</string>
<string name="find_device_you_found_it">Намери ме!</string>
<string name="kind_font">Шрифт</string>
<string name="kind_invalid">Невалидни данни</string>
<string name="live_activity_heart_rate">Сърдечен ритъм</string>
<string name="maximum_duration">Продължителност</string>
<string name="menuitem_alarm">Аларма</string>
<string name="menuitem_activity">Активност</string>
<string name="menuitem_compass">Компас</string>
<string name="menuitem_music">Музика</string>
<string name="menuitem_settings">Настройки</string>
<string name="menuitem_notifications">Известия</string>
<string name="menuitem_weather">Прогноза за време</string>
<string name="menuitem_timer">Таймер</string>
<string name="mi2_dnd_off">Изкл.</string>
<string name="mi2_dnd_scheduled">Разписание</string>
<string name="mi2_prefs_do_not_disturb_end">Край</string>
<string name="mi2_prefs_do_not_disturb_start">Начало</string>
<string name="mi2_prefs_do_not_disturb">Не безпокой</string>
<string name="you_slept">Вие спахте от %1$s до %2$s</string>
<string name="wxp_power_mode_title">Режим на часовника</string>
<string name="wxp_mode_watch">Само часовник</string>
<string name="wxp_mode_saving">Икономичен</string>
<string name="wxp_mode_normal">Нормален</string>
<string name="widget_steps_label">Стъпки: %1$02d</string>
<string name="widget_sleep_label">Сън: %1$s</string>
<string name="widget_5_minutes">5 минути</string>
<string name="widget_20_minutes">20 минути</string>
<string name="widget_1_hour">1 час</string>
<string name="widget_10_minutes">10 минути</string>
<string name="weekstepschart_steps_a_month">Крачки за месец</string>
<string name="weeksleepchart_sleep_a_month">Сън за месец</string>
<string name="warning">Внимание!</string>
<string name="waiting_for_reconnect">Изчаква свързване</string>
<string name="user_feedback_all_alarms_disabled">Всички аларми са изключени</string>
<string name="unit_metric">Метрична</string>
<string name="unit_imperial">Инчова</string>
<string name="toast_notification_filter_words_empty_hint">Въведете поне една дума</string>
<string name="toast_notification_filter_saved_successfully">Филтъра за известия е запазен</string>
<string name="title_activity_vibration">Вибрация</string>
<string name="title_activity_notification_filter">Филтър за известия</string>
<string name="title_activity_db_management">Управление на БД</string>
<string name="select_all">Избери всички</string>
<string name="share">Сподели</string>
<string name="save_configuration">Запази настройките</string>
<string name="prefs_wxp_button_bp_calibration_sum">Натисни тук за старт на калибрирането</string>
<string name="prefs_wxp_button_bp_calibration">Започни калибриране</string>
<string name="prefs_hr_alarm_high">Горна граница</string>
<string name="prefs_hr_alarm_low">Долна граница</string>
<string name="preferences_rtl_settings">От ляво на дясно</string>
<string name="pref_screen_notification_profile_alarm_clock">Аларми</string>
<string name="pref_header_wxp_settings">WatchXPlus настройки</string>
<string name="p_unit_metric">метрични</string>
<string name="p_unit_imperial">инчови</string>
<string name="p_steps">крачки</string>
<string name="p_scheduled">разписание</string>
<string name="p_pebble_privacy_mode_off">изкл.</string>
<string name="p_on">вкл.</string>
<string name="p_off">изкл.</string>
<string name="p_menuitem_weather">прогноза</string>
<string name="p_menuitem_settings">настройки</string>
<string name="p_menuitem_notifications">известия</string>
<string name="off">Изкл.</string>
<string name="on">Вкл.</string>
<string name="no_data">Няма данни</string>
</resources> </resources>

View File

@ -69,6 +69,17 @@
<item>never</item> <item>never</item>
</string-array> </string-array>
<string-array name="wxp_mode">
<item name="0">@string/wxp_mode_normal</item>
<item name="1">@string/wxp_mode_saving</item>
<item name="2">@string/wxp_mode_watch</item>
</string-array>
<string-array name="wxp_mode_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string-array name="gender"> <string-array name="gender">
<item name="1">@string/male</item> <item name="1">@string/male</item>
<item name="0">@string/female</item> <item name="0">@string/female</item>

View File

@ -205,6 +205,11 @@
<string name="prefs_wxp_button_bp_calibration">Begin calibration</string> <string name="prefs_wxp_button_bp_calibration">Begin calibration</string>
<string name="prefs_wxp_button_bp_calibration_sum">Press here to begin calibration</string> <string name="prefs_wxp_button_bp_calibration_sum">Press here to begin calibration</string>
<string name="pref_header_wxp_calibration">WatchXPlus calibration</string> <string name="pref_header_wxp_calibration">WatchXPlus calibration</string>
<string name="pref_header_wxp_settings">WatchXPlus settings</string>
<string name="wxp_power_mode_title">Watch mode</string>
<string name="wxp_mode_normal">Normal</string>
<string name="wxp_mode_saving">Power saving</string>
<string name="wxp_mode_watch">Only watch</string>
<!-- Makibes HR3 Preferences --> <!-- Makibes HR3 Preferences -->
<string name="preferences_makibes_hr3_settings">Makibes HR3 settings</string> <string name="preferences_makibes_hr3_settings">Makibes HR3 settings</string>
<!-- ID115 Preferences --> <!-- ID115 Preferences -->

View File

@ -611,8 +611,20 @@
android:summary="@string/pref_wxp_title_shake_reject_summary" android:summary="@string/pref_wxp_title_shake_reject_summary"
android:title="@string/prefs_wxp_shake_reject" /> android:title="@string/prefs_wxp_shake_reject" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:key="pref_category_watchxplus_calibration" android:key="pref_category_watchxplus_calibration"
android:title="@string/pref_header_wxp_settings">
<ListPreference
android:defaultValue="0"
android:title="@string/wxp_power_mode_title"
android:entries="@array/wxp_mode"
android:entryValues="@array/wxp_mode_values"
android:key="wxp_power_mode"
android:summary="%s" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_category_watchxplus_settings"
android:title="@string/pref_header_wxp_calibration"> android:title="@string/pref_header_wxp_calibration">
<EditTextPreference <EditTextPreference
@ -638,13 +650,30 @@
<CheckBoxPreference <CheckBoxPreference
android:layout="@layout/preference_checkbox" android:layout="@layout/preference_checkbox"
android:defaultValue="false" android:defaultValue="false"
android:key="watchxplus_button_BP_calibration" android:key="wxp_button_BP_calibration"
android:summary="@string/prefs_wxp_button_bp_calibration_sum" android:summary="@string/prefs_wxp_button_bp_calibration_sum"
android:title="@string/prefs_wxp_button_bp_calibration" /> android:title="@string/prefs_wxp_button_bp_calibration" />
</PreferenceScreen> </PreferenceScreen>
</PreferenceCategory> </PreferenceCategory>
<!--
<PreferenceCategory
android:key="pref_category_watchxplus_test"
android:title="Test new commands"
android:summary="!!!Warning!!!">
<EditTextPreference
android:inputType="number"
android:key="wxp_newcmd_first"
android:defaultValue="5"
android:title="first byte (dec)"
android:summary="%s"/>
<EditTextPreference
android:inputType="number"
android:key="wxp_newcmd_second"
android:defaultValue="5"
android:title="second byte (dec)"
android:summary="%s"/>
</PreferenceCategory>
-->
</PreferenceScreen> </PreferenceScreen>
</PreferenceCategory> </PreferenceCategory>