Merge pull request #455 from AdrianLxM/wear-flavours

profile work and wear flavours
This commit is contained in:
AdrianLxM 2017-10-12 23:10:27 +02:00 committed by GitHub
commit 729023b010
25 changed files with 500 additions and 218 deletions

View file

@ -62,7 +62,7 @@ android {
}
}
productFlavors {
flavorDimensions "standard", "wear"
flavorDimensions "standard"
full {
dimension "standard"
resValue "string", "app_name", "AndroidAPS"
@ -111,22 +111,6 @@ android {
buildConfigField "boolean", "NSCLIENTOLNY", "true"
buildConfigField "boolean", "CLOSEDLOOP", "false"
}
wear {
dimension "wear"
buildConfigField "boolean", "WEAR", "true"
buildConfigField "boolean", "WEAR_CONTROL", "false"
}
wearcontrol {
dimension "wear"
buildConfigField "boolean", "WEAR", "true"
buildConfigField "boolean", "WEAR_CONTROL", "true"
}
nowear {
dimension "wear"
buildConfigField "boolean", "WEAR", "false"
buildConfigField "boolean", "WEAR_CONTROL", "false"
}
}
}
@ -140,8 +124,7 @@ allprojects {
}
dependencies {
wearWearApp project(path: ':wear', configuration: 'restrictedRelease')
wearcontrolWearApp project(path: ':wear', configuration: 'fullRelease')
wearApp project(':wear')
compile fileTree(include: ['*.jar'], dir: 'libs')
compile('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {

View file

@ -11,7 +11,6 @@ public class Config {
// PLUGINS
public static final boolean OPENAPSENABLED = APS;
public static final boolean LOOPENABLED = APS;
public static final boolean WEAR = BuildConfig.WEAR;
public static final boolean NSCLIENT = BuildConfig.NSCLIENTOLNY;

View file

@ -33,7 +33,7 @@ public class Constants {
public static final int CPP_MIN_PERCENTAGE = 50;
public static final int CPP_MAX_PERCENTAGE = 200;
public static final int CPP_MIN_TIMESHIFT = -6;
public static final int CPP_MAX_TIMESHIFT = 6;
public static final int CPP_MAX_TIMESHIFT = 23;
// Very Hard Limits Ranges
// First value is the Lowest and second value is the Highest a Limit can define

View file

@ -150,7 +150,7 @@ public class MainApp extends Application {
pluginsList.add(SourceGlimpPlugin.getPlugin());
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin());
if (Config.WEAR) pluginsList.add(WearFragment.getPlugin(this));
pluginsList.add(WearFragment.getPlugin(this));
pluginsList.add(StatuslinePlugin.getPlugin(this));
pluginsList.add(new PersistentNotificationPlugin(this));
pluginsList.add(NSClientInternalPlugin.getPlugin());

View file

@ -170,12 +170,10 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
}
addPreferencesFromResource(R.xml.pref_advanced);
if (Config.WEAR) {
WearPlugin wearPlugin = MainApp.getSpecificPlugin(WearPlugin.class);
if (wearPlugin != null && wearPlugin.isEnabled(PluginBase.GENERAL)) {
addPreferencesFromResource(R.xml.pref_wear);
}
}
StatuslinePlugin statuslinePlugin = MainApp.getSpecificPlugin(StatuslinePlugin.class);
if (statuslinePlugin != null && statuslinePlugin.isEnabled(PluginBase.GENERAL)) {

View file

@ -18,6 +18,8 @@ import info.nightscout.androidaps.interfaces.Interval;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SafeParse;
@DatabaseTable(tableName = DatabaseHelper.DATABASE_PROFILESWITCHES)
public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
@ -66,7 +68,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
}
public String getCustomizedName() {
String name = profileName;
String name = DecimalFormatter.to2Decimal(getProfileObject().percentageBasalSum()) + "U ";
if (isCPP) {
name += "(" + percentage + "%," + timeshift + "h)";
}
@ -187,7 +189,7 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
@Override
public String getLabel() {
return profileName;
return getCustomizedName();
}
@Override

View file

@ -16,6 +16,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
@ -75,6 +76,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
TextView eventTypeText;
LinearLayout layoutPercent;
LinearLayout layoutAbsolute;
LinearLayout layoutReuse;
TextView dateButton;
TextView timeButton;
@ -86,6 +89,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
EditText notesEdit;
Spinner profileSpinner;
Spinner reasonSpinner;
Button reuseButton;
NumberPicker editBg;
NumberPicker editCarbs;
@ -141,6 +145,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
layoutPercent = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_percent_layout);
layoutAbsolute = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_absolute_layout);
layoutReuse = (LinearLayout) view.findViewById(R.id.careportal_newnstreatment_reuse_layout);
eventTypeText = (TextView) view.findViewById(R.id.careportal_newnstreatment_eventtype);
eventTypeText.setText(event);
bgUnitsView = (TextView) view.findViewById(R.id.careportal_newnstreatment_bgunits);
@ -149,6 +155,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
otherRadioButton = (RadioButton) view.findViewById(R.id.careportal_newnstreatment_other);
profileSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_profile);
reuseButton = (Button) view.findViewById(R.id.careportal_newnstreatment_reusebutton);
notesEdit = (EditText) view.findViewById(R.id.careportal_newnstreatment_notes);
reasonSpinner = (Spinner) view.findViewById(R.id.careportal_newnstreatment_temptarget_reason);
@ -322,11 +330,25 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
editPercentage = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentage);
editPercentage.setParams(100d, (double) Constants.CPP_MIN_PERCENTAGE, (double) Constants.CPP_MAX_PERCENTAGE, 5d, new DecimalFormat("0"), false);
editPercentage.setParams(100d, (double) Constants.CPP_MIN_PERCENTAGE, (double) Constants.CPP_MAX_PERCENTAGE, 1d, new DecimalFormat("0"), false);
editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift);
editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false);
ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
if(ps!=null && ps.isCPP){
final int percentage = ps.percentage;
final int timeshift = ps.timeshift;
reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift +"h");
reuseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editPercentage.setValue((double)percentage);
editTimeshift.setValue((double)timeshift);
}
});
}
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bgsource_layout), options.bg);
@ -340,6 +362,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_profile_layout), options.profile);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_percentage_layout), options.profile);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_timeshift_layout), options.profile);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_reuse_layout), options.profile && ps!=null && ps.isCPP);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_temptarget_layout), options.tempTarget);
return view;
@ -722,18 +745,17 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
@Override
public void run() {
ProfileSwitch profileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
if (profileSwitch == null) {
if (profileSwitch != null) {
profileSwitch = new ProfileSwitch();
profileSwitch.date = System.currentTimeMillis();
profileSwitch.source = Source.USER;
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName();
profileSwitch.profileName = MainApp.getConfigBuilder().getProfileName(System.currentTimeMillis(), false);
profileSwitch.profileJson = MainApp.getConfigBuilder().getProfile().getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration;
profileSwitch.isCPP = percentage != 100 || timeshift != 0;
profileSwitch.timeshift = timeshift;
profileSwitch.percentage = percentage;
}
MainApp.getConfigBuilder().addToHistoryProfileSwitch(profileSwitch);
PumpInterface pump = MainApp.getConfigBuilder();
@ -744,6 +766,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
log.error("No active pump selected");
}
Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch"));
} else {
log.error("No profile switch existing");
}
}
});
}

View file

@ -934,10 +934,14 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain
}
public String getProfileName(long time) {
return getProfileName(time, true);
}
public String getProfileName(long time, boolean customized) {
ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time);
if (profileSwitch != null) {
if (profileSwitch.profileJson != null) {
return profileSwitch.getCustomizedName();
return customized?profileSwitch.getCustomizedName():profileSwitch.profileName;
} else {
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName);
if (profile != null)

View file

@ -2,7 +2,9 @@ package info.nightscout.androidaps.plugins.ProfileCircadianPercentage;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.DialogFragment;
@ -123,6 +125,9 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
showDeprecatedDialog();
View layout = inflater.inflate(R.layout.circadianpercentageprofile_fragment, container, false);
fl = (FrameLayout) layout.findViewById(R.id.circadianpercentageprofile_framelayout);
fl.requestFocusFromTouch();
@ -230,7 +235,7 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
}
});
timeshiftView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
/*timeshiftView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
@ -266,7 +271,7 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
}
}
}
});
});*/
diaView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@ -315,6 +320,25 @@ public class CircadianPercentageProfileFragment extends SubscriberFragment {
return layout;
}
private void showDeprecatedDialog() {
AlertDialog.Builder adb = new AlertDialog.Builder(getContext());
adb.setTitle("DEPRECATED! Please migrate!");
adb.setMessage("CircadianPercentageProfile has been deprecated. " +
"It is recommended to migrate to LocalProfile.\n\n" +
"Good news: You won't lose any functionality! Percentage and Timeshift have been ported to the ProfileSwitch :) \n\n " +
"How to migrate:\n" +
"1) Press MIGRATE, the system will automatically fill the LocalProfile for you.\n" +
"2) Switch to LocalProfile in the ConfigBuilder\n" +
"3) CHECK that all settings are correct in the LocalProfile!!!");
adb.setIcon(android.R.drawable.ic_dialog_alert);
adb.setPositiveButton("MIGRATE", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
CircadianPercentageProfilePlugin.migrateToLP();
} });
adb.setNegativeButton("Cancel", null);
adb.show();
}
public void updateGUI() {
updateProfileInfo();

View file

@ -21,6 +21,8 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.SP;
@ -211,6 +213,91 @@ public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInte
return msg;
}
public static void migrateToLP(){
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("LocalProfile" + "mmol", SP.getBoolean(SETTINGS_PREFIX + "mmol", false));
editor.putBoolean("LocalProfile" + "mgdl", SP.getBoolean(SETTINGS_PREFIX + "mgdl", true));
editor.putString("LocalProfile" + "dia", "" + SP.getDouble(SETTINGS_PREFIX + "dia", Constants.defaultDIA));
editor.putString("LocalProfile" + "ic", getLPisf());
editor.putString("LocalProfile" + "isf", getLPisf());
editor.putString("LocalProfile" + "basal", getLPbasal());
try {
JSONArray targetLow = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targetlow", 120d)));
JSONArray targetHigh = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targethigh", 120d)));
editor.putString("LocalProfile" + "targetlow", targetLow.toString());
editor.putString("LocalProfile" + "targethigh", targetHigh.toString());
} catch (JSONException e) {
e.printStackTrace();
}
editor.commit();
LocalProfilePlugin lp = MainApp.getSpecificPlugin(LocalProfilePlugin.class);
lp.loadSettings();
/* TODO: remove Settings and switch to LP later on
* For now only nag the user every time (s)he opens the CPP fragment and offer to migrate.
* Keep settings for now in order to allow the user to check that the migration went well.
*/
//removeSettings();
}
public static String getLPisf(){
return getLPConversion("baseisf", 35d);
}
public static String getLPic(){
return getLPConversion("baseic", 4);
}
public static String getLPbasal(){
return getLPConversion("basebasal", 1);
}
public static String getLPConversion(String type, double defaultValue){
try {
JSONArray jsonArray = new JSONArray();
double last = -1d;
for (int i = 0; i < 24; i++) {
double value = SP.getDouble(SETTINGS_PREFIX + type + i, defaultValue);
String time;
DecimalFormat df = new DecimalFormat("00");
time = df.format(i) + ":00";
if(last != value) {
jsonArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", value));
}
last = value;
}
return jsonArray.toString();
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return LocalProfilePlugin.DEFAULTARRAY;
}
static void removeSettings() {
if (Config.logPrefsChange)
log.debug("Removing settings");
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = settings.edit();
editor.remove(SETTINGS_PREFIX + "mmol");
editor.remove(SETTINGS_PREFIX + "mgdl");
editor.remove(SETTINGS_PREFIX + "dia");
editor.remove(SETTINGS_PREFIX + "targetlow");
editor.remove(SETTINGS_PREFIX + "targethigh");
editor.remove(SETTINGS_PREFIX + "timeshift");
editor.remove(SETTINGS_PREFIX + "percentage");
for (int i = 0; i < 24; i++) {
editor.remove(SETTINGS_PREFIX + "basebasal");
editor.remove(SETTINGS_PREFIX + "baseisf" + i);
editor.remove(SETTINGS_PREFIX + "baseic" + i);
}
editor.commit();
}
private void createConvertedProfile() {
JSONObject json = new JSONObject();
JSONObject store = new JSONObject();

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.ProfileLocal;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
@ -27,6 +28,7 @@ import info.nightscout.androidaps.plugins.Careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.TimeListEdit;
@ -57,6 +59,9 @@ public class LocalProfileFragment extends SubscriberFragment {
@Override
public void run() {
localProfilePlugin.storeSettings();
if(basalView!=null){
basalView.updateLabel(MainApp.sResources.getString(R.string.nsprofileview_basal_label)+ ": "+ getSumLabel());
}
}
};
@ -84,10 +89,10 @@ public class LocalProfileFragment extends SubscriberFragment {
diaView.setParams(localProfilePlugin.dia, 2d, 48d, 0.1d, new DecimalFormat("0.0"), false, textWatch);
mgdlView = (RadioButton) layout.findViewById(R.id.localprofile_mgdl);
mmolView = (RadioButton) layout.findViewById(R.id.localprofile_mmol);
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label), getPlugin().ic, null, 0.1d, new DecimalFormat("0.0"), save);
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label), getPlugin().isf, null, 0.1d, new DecimalFormat("0.0"), save);
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label), getPlugin().basal, null, 0.01d, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label), getPlugin().targetLow, getPlugin().targetHigh, 0.1d, new DecimalFormat("0.0"), save);
icView = new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.sResources.getString(R.string.nsprofileview_ic_label) + ":", getPlugin().ic, null, 0.1d, new DecimalFormat("0.0"), save);
isfView = new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.sResources.getString(R.string.nsprofileview_isf_label) + ":", getPlugin().isf, null, 0.1d, new DecimalFormat("0.0"), save);
basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.sResources.getString(R.string.nsprofileview_basal_label)+ ": " + getSumLabel(), getPlugin().basal, null, 0.01d, new DecimalFormat("0.00"), save);
targetView = new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.sResources.getString(R.string.nsprofileview_target_label)+ ":", getPlugin().targetLow, getPlugin().targetHigh, 0.1d, new DecimalFormat("0.0"), save);
profileswitchButton = (Button) layout.findViewById(R.id.localprofile_profileswitch);
PumpInterface pump = MainApp.getConfigBuilder();
@ -141,6 +146,11 @@ public class LocalProfileFragment extends SubscriberFragment {
return null;
}
@NonNull
public String getSumLabel() {
return "" + DecimalFormatter.to2Decimal(localProfilePlugin.getProfile().getDefaultProfile().baseBasalSum()) +"U";
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged e) {
updateGUI();

View file

@ -30,7 +30,7 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface {
private ProfileStore convertedProfile = null;
private String convertedProfileName = null;
final private String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]";
public static final String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]";
boolean mgdl;
boolean mmol;
@ -124,7 +124,7 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface {
log.debug("Storing settings: " + getProfile().getData().toString());
}
private void loadSettings() {
public void loadSettings() {
if (Config.logPrefsChange)
log.debug("Loading stored settings");

View file

@ -23,18 +23,20 @@ import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DanaRHistoryRecord;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.DanaRInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Loop.APSResult;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfilePlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump;
import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes;
@ -67,8 +69,7 @@ public class ActionStringHandler {
public synchronized static void handleInitiate(String actionstring) {
if (!BuildConfig.WEAR_CONTROL) return;
if (!SP.getBoolean("wearcontrol", false)) return;
lastBolusWizard = null;
@ -242,25 +243,21 @@ public class ActionStringHandler {
lastBolusWizard = bolusWizard;
} else if("opencpp".equals(act[0])){
Object activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
CircadianPercentageProfilePlugin cpp = MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class);
if(cpp == null || activeProfile==null || cpp != activeProfile){
sendError("CPP not activated!");
ProfileSwitch activeProfileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
if(activeProfileSwitch==null){
sendError("No active profile switch!");
return;
} else {
// read CPP values
rTitle = "opencpp";
rMessage = "opencpp";
rAction = "opencpp" + " " + cpp.getPercentage() + " " + cpp.getTimeshift();
rAction = "opencpp" + " " + activeProfileSwitch.percentage + " " + activeProfileSwitch.timeshift;
}
} else if("cppset".equals(act[0])){
Object activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
CircadianPercentageProfilePlugin cpp = MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class);
if(cpp == null || activeProfile==null || cpp != activeProfile){
sendError("CPP not activated!");
ProfileSwitch activeProfileSwitch = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis());
if(activeProfileSwitch==null){
sendError("No active profile switch!");
return;
} else {
// read CPP values
@ -334,13 +331,16 @@ public class ActionStringHandler {
private static String generateTDDMessage(List<DanaRHistoryRecord> historyList, List<DanaRHistoryRecord> dummies) {
ProfileInterface activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
if(activeProfile == null){
return "No profile loaded :(";
}
DateFormat df = new SimpleDateFormat("dd.MM.");
String message = "";
CircadianPercentageProfilePlugin cpp = MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class);
boolean isCPP = (cpp!= null && cpp.isEnabled(PluginBase.PROFILE));
double refTDD = 100;
if(isCPP) refTDD = cpp.baseBasalSum()*2;
double refTDD = activeProfile.getProfile().getDefaultProfile().baseBasalSum()*2;
int i = 0;
double sum = 0d;
@ -364,15 +364,15 @@ public class ActionStringHandler {
i++;
}
message += "weighted:\n";
message += "0.3: " + DecimalFormatter.to2Decimal(weighted03) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*weighted03/refTDD) + "%"):"") + "\n";
message += "0.5: " + DecimalFormatter.to2Decimal(weighted05) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*weighted05/refTDD) + "%"):"") + "\n";
message += "0.7: " + DecimalFormatter.to2Decimal(weighted07) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*weighted07/refTDD) + "%"):"") + "\n";
message += "0.3: " + DecimalFormatter.to2Decimal(weighted03) + "U " + (DecimalFormatter.to0Decimal(100*weighted03/refTDD) + "%") + "\n";
message += "0.5: " + DecimalFormatter.to2Decimal(weighted05) + "U " + (DecimalFormatter.to0Decimal(100*weighted05/refTDD) + "%") + "\n";
message += "0.7: " + DecimalFormatter.to2Decimal(weighted07) + "U " + (DecimalFormatter.to0Decimal(100*weighted07/refTDD) + "%") + "\n";
message += "\n";
PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
if (pump != null && pump instanceof DanaRPlugin) {
double tdd = DanaRPump.getInstance().dailyTotalUnits;
message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (isCPP?(DecimalFormatter.to0Decimal(100*tdd/refTDD) + "%"):"") + "\n";
message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (DecimalFormatter.to0Decimal(100*tdd/refTDD) + "%") + "\n";
message += "\n";
}
@ -380,7 +380,7 @@ public class ActionStringHandler {
Collections.reverse(historyList);
for (DanaRHistoryRecord record : historyList) {
double tdd = record.recordDailyBolus + record.recordDailyBasal;
message += df.format(new Date(record.recordDate)) + " " + DecimalFormatter.to2Decimal(tdd) +"U " + (isCPP?(DecimalFormatter.to0Decimal(100*tdd/refTDD) + "%"):"") + (dummies.contains(record)?"x":"") +"\n";
message += df.format(new Date(record.recordDate)) + " " + DecimalFormatter.to2Decimal(tdd) +"U " + (DecimalFormatter.to0Decimal(100*tdd/refTDD) + "%") + (dummies.contains(record)?"x":"") +"\n";
}
return message;
}
@ -521,7 +521,7 @@ public class ActionStringHandler {
public synchronized static void handleConfirmation(String actionString) {
if (!BuildConfig.WEAR_CONTROL) return;
if (!SP.getBoolean("wearcontrol", false)) return;
//Guard from old or duplicate confirmations
@ -564,29 +564,47 @@ public class ActionStringHandler {
} else if ("cppset".equals(act[0])) {
int timeshift = SafeParse.stringToInt(act[1]);
int percentage = SafeParse.stringToInt(act[2]);
setCPP(percentage, timeshift);
setCPP(timeshift, percentage);
} else if ("dismissoverviewnotification".equals(act[0])){
MainApp.bus().post(new EventDismissNotification(SafeParse.stringToInt(act[1])));
}
lastBolusWizard = null;
}
private static void setCPP(int percentage, int timeshift) {
Object activeProfile = MainApp.getConfigBuilder().getActiveProfileInterface();
CircadianPercentageProfilePlugin cpp = MainApp.getSpecificPlugin(CircadianPercentageProfilePlugin.class);
private static void setCPP(int timeshift, int percentage) {
if(cpp == null || activeProfile==null || cpp != activeProfile){
sendError("CPP not activated!");
return;
String msg = "";
//check for validity
if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) {
msg+= String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage") + "\n";
}
String msg = cpp.externallySetParameters(timeshift, percentage);
if(msg != null && !"".equals(msg)){
if (timeshift < 0 || timeshift > 23) {
msg+= String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Timeshift") + "\n";
}
if(!SP.getBoolean("syncprofiletopump", false)){
msg+= MainApp.sResources.getString(R.string.syncprofiletopump_title) + " " + MainApp.sResources.getString(R.string.cpp_sync_setting_missing) + "\n";
}
final PumpInterface pump = MainApp.getConfigBuilder();
final Profile profile = MainApp.getConfigBuilder().getProfile();
if (pump == null || profile == null || profile.getBasal() == null){
msg+= MainApp.sResources.getString(R.string.cpp_notloadedplugins) + "\n";
}
if(!"".equals(msg)) {
msg += MainApp.sResources.getString(R.string.cpp_valuesnotstored);
String rTitle = "STATUS";
String rAction = "statusmessage";
WearFragment.getPlugin(MainApp.instance()).requestActionConfirmation(rTitle, msg, rAction);
lastSentTimestamp = System.currentTimeMillis();
lastConfirmActionString = rAction;
return;
}
//send profile to pumpe
new NewNSTreatmentDialog(); //init
NewNSTreatmentDialog.doProfileSwitch(0, percentage, timeshift);
}
private static void generateTempTarget(int duration, double low, double high) {

View file

@ -29,7 +29,7 @@ import info.nightscout.utils.SP;
public class WearPlugin implements PluginBase {
private static boolean fragmentEnabled = Config.WEAR;
private static boolean fragmentEnabled = true;
private boolean fragmentVisible = true;
private static WatchUpdaterService watchUS;
private final Context ctx;

View file

@ -42,6 +42,7 @@ import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.Wear.ActionStringHandler;
import info.nightscout.androidaps.plugins.Wear.WearPlugin;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
@ -65,6 +66,7 @@ public class WatchUpdaterService extends WearableListenerService implements
private static final String OPEN_SETTINGS_PATH = "/openwearsettings";
private static final String NEW_STATUS_PATH = "/sendstatustowear";
private static final String NEW_PREFERENCES_PATH = "/sendpreferencestowear";
public static final String BASAL_DATA_PATH = "/nightscout_watch_basal";
public static final String BOLUS_PROGRESS_PATH = "/nightscout_watch_bolusprogress";
public static final String ACTION_CONFIRMATION_REQUEST_PATH = "/nightscout_watch_actionconfirmationrequest";
@ -326,6 +328,7 @@ public class WatchUpdaterService extends WearableListenerService implements
entries.putDataMapArrayList("entries", dataMaps);
new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(entries);
}
sendPreferences();
sendBasals();
sendStatus();
}
@ -527,6 +530,22 @@ public class WatchUpdaterService extends WearableListenerService implements
}
}
private void sendPreferences() {
if (googleApiClient.isConnected()) {
boolean wearcontrol = SP.getBoolean("wearcontrol",false);
PutDataMapRequest dataMapRequest = PutDataMapRequest.create(NEW_PREFERENCES_PATH);
//unique content
dataMapRequest.getDataMap().putDouble("timestamp", System.currentTimeMillis());
dataMapRequest.getDataMap().putBoolean("wearcontrol", wearcontrol);
PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
} else {
Log.e("SendStatus", "No connection to wearable available!");
}
}
@NonNull
private String generateStatusString() {
String status = "";

View file

@ -1,5 +1,6 @@
package info.nightscout.utils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
@ -69,6 +70,7 @@ import android.widget.SpinnerAdapter;
*/
public class SpinnerHelper implements OnItemSelectedListener {
private final Spinner spinner;
private boolean userTouched;
private int lastPosition = -1;
private OnItemSelectedListener proxiedItemSelectedListener = null;
@ -93,11 +95,22 @@ public class SpinnerHelper implements OnItemSelectedListener {
public void setOnItemSelectedListener(OnItemSelectedListener listener) {
proxiedItemSelectedListener = listener;
setTouchListener();
spinner.setOnItemSelectedListener(listener == null ? null : this);
}
public void setTouchListener() {
spinner.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
userTouched = true;
return false;
}
});
}
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (position != lastPosition) {
if (position != lastPosition && userTouched) {
lastPosition = position;
if (proxiedItemSelectedListener != null) {
proxiedItemSelectedListener.onItemSelected(

View file

@ -53,6 +53,10 @@ public class TimeListEdit {
private double step;
private NumberFormat formatter;
private Runnable save;
private LinearLayout layout;
private TextView textlabel;
private int inflatedUntil = -1;
public TimeListEdit(Context context, View view, int resLayoutId, String label, JSONArray data1, JSONArray data2, double step, NumberFormat formatter, Runnable save) {
this.context = context;
@ -68,9 +72,9 @@ public class TimeListEdit {
}
private void buildView() {
LinearLayout layout = (LinearLayout) view.findViewById(resLayoutId);
layout = (LinearLayout) view.findViewById(resLayoutId);
TextView textlabel = new TextView(context);
textlabel = new TextView(context);
textlabel.setText(label);
textlabel.setGravity(Gravity.START);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
@ -80,7 +84,34 @@ public class TimeListEdit {
TextViewCompat.setTextAppearance(textlabel, android.R.style.TextAppearance_Medium);
layout.addView(textlabel);
for (int i = 0; i < 24; i++) {
for (int i = 0; i < 24 && i < itemsCount(); i++) {
inflateRow(i);
inflatedUntil = i;
}
// last "plus" to append new interval
finalAdd = new ImageView(context);
finalAdd.setImageResource(R.drawable.add);
LinearLayout.LayoutParams illp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
illp.setMargins(0, 25, 0, 25); // llp.setMargins(left, top, right, bottom);
illp.gravity = Gravity.CENTER;
layout.addView(finalAdd);
finalAdd.setLayoutParams(illp);
finalAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addItem(itemsCount(), itemsCount() > 0 ? secondFromMidnight(itemsCount() - 1) + ONEHOURINSECONDS : 0, 0, 0);
callSave();
log();
fillView();
}
});
fillView();
}
private void inflateRow(int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View childview = intervals[i] = inflater.inflate(R.layout.timelistedit_element, layout, false);
spinners[i] = new SpinnerHelper(childview.findViewById(R.id.timelistedit_time));
@ -178,35 +209,15 @@ public class TimeListEdit {
layout.addView(childview);
}
// last "plus" to append new interval
finalAdd = new ImageView(context);
finalAdd.setImageResource(R.drawable.add);
LinearLayout.LayoutParams illp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
illp.setMargins(0, 25, 0, 25); // llp.setMargins(left, top, right, bottom);
illp.gravity = Gravity.CENTER;
layout.addView(finalAdd);
finalAdd.setLayoutParams(illp);
finalAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addItem(itemsCount(), itemsCount() > 0 ? secondFromMidnight(itemsCount() - 1) + ONEHOURINSECONDS : 0, 0, 0);
callSave();
log();
fillView();
}
});
fillView();
}
private void fillView() {
for (int i = 0; i < 24; i++) {
if (i < itemsCount()) {
intervals[i].setVisibility(View.VISIBLE);
buildInterval(i);
} else
} else if (i <= inflatedUntil){
intervals[i].setVisibility(View.GONE);
}
}
if (!(itemsCount() > 0 && secondFromMidnight(itemsCount() - 1) == 23 * ONEHOURINSECONDS)) {
finalAdd.setVisibility(View.VISIBLE);
@ -339,6 +350,11 @@ public class TimeListEdit {
}
private void addItem(int index, int timeAsSeconds, double value1, double value2) {
if(itemsCount()>inflatedUntil) {
layout.removeView(finalAdd);
inflateRow(++inflatedUntil);
layout.addView(finalAdd);
}
try {
// shift data
for (int i = data1.length(); i > index; i--) {
@ -371,4 +387,10 @@ public class TimeListEdit {
private void callSave() {
if (save != null) save.run();
}
public void updateLabel(String txt){
this.label = txt;
if(textlabel!=null)
textlabel.setText(txt);
}
}

View file

@ -408,6 +408,41 @@
</LinearLayout>
<LinearLayout
android:id="@+id/careportal_newnstreatment_reuse_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:width="120dp"
android:padding="10dp"
android:text=""
android:textAppearance="@android:style/TextAppearance.Material.Small"
android:textStyle="bold" />
<Button
android:id="@+id/careportal_newnstreatment_reusebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reuse"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:text=" "
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<LinearLayout
android:id="@+id/careportal_newnstreatment_percentage_layout"
android:layout_width="match_parent"

View file

@ -17,6 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/linearBlockBackground"
android:layout_marginLeft="10px"
android:text="@string/units"
android:textAppearance="?android:attr/textAppearanceMedium" />
@ -44,16 +45,58 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/linearBlockBackground"
android:layout_marginLeft="10px"
android:text="@string/dia"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingTop="5dp"
android:textAppearance="?android:attr/textAppearanceSmall">
<!-- dummy to align with TimeListEdits added dynamically -->
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginRight="10dp"
android:minWidth="80dp"
android:visibility="invisible"/>
<info.nightscout.utils.NumberPicker
android:id="@+id/localprofile_dia"
android:layout_width="130dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginRight="5dp"
android:layout_marginBottom="10dp"/>
<!-- dummy to align with TimeListEdits added dynamically -->
<ImageView
android:id="@+id/timelistedit_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:src="@drawable/add"
android:visibility="invisible"/>
<!-- dummy to align with TimeListEdits added dynamically -->
<ImageView
android:id="@+id/timelistedit_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:src="@drawable/remove"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:id="@+id/localprofile_ic"
android:layout_width="match_parent"

View file

@ -742,5 +742,8 @@
<string name="gettingtempbasalstatus">Getting temporary basal status</string>
<string name="gettingpumpsettings">Gettings pump settings</string>
<string name="gettingpumptime">Getting pump time</string>
<string name="reuse">reuse</string>
<string name="wearcontrol_title">Controls from Watch</string>
<string name="wearcontrol_summary">Set Temp-Targets and enter Treatments from the watch.</string>
</resources>

View file

@ -4,6 +4,12 @@
android:key="wearplugin"
android:title="@string/wear_settings">
<SwitchPreference
android:defaultValue="false"
android:key="wearcontrol"
android:title="@string/wearcontrol_title"
android:summary="@string/wearcontrol_summary"/>
<SwitchPreference
android:defaultValue="true"
android:key="wear_detailediob"

View file

@ -42,33 +42,6 @@ android {
publishNonDefault true
productFlavors {
full {
applicationId = "info.nightscout.androidaps"
resValue "string", "label_xdrip", "AAPS"
resValue "string", "label_xdrip_large", "AAPS(Large)"
resValue "string", "label_xdrip_big_chart", "AAPS(BigChart)"
resValue "string", "label_xdrip_no_chart", "AAPS(NoChart)"
resValue "string", "label_xdrip_circle", "AAPS(Circle)"
resValue "string", "label_xdrip_activity", "AAPS Prefs."
resValue "string", "app_settings", "AAPS Settings"
buildConfigField "boolean", "WEAR_CONTROL", "true"
}
restricted {
applicationId = "info.nightscout.androidaps"
resValue "string", "label_xdrip", "AAPS"
resValue "string", "label_xdrip_large", "AAPS(Large)"
resValue "string", "label_xdrip_big_chart", "AAPS(BigChart)"
resValue "string", "label_xdrip_no_chart", "AAPS(NoChart)"
resValue "string", "label_xdrip_circle", "AAPS(Circle)"
resValue "string", "label_xdrip_activity", "AAPS Prefs."
resValue "string", "app_settings", "AAPS Settings"
buildConfigField "boolean", "WEAR_CONTROL", "false"
}
}
}
allprojects {

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.data;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
@ -43,6 +44,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp
private static final String OPEN_SETTINGS = "/openwearsettings";
private static final String NEW_STATUS_PATH = "/sendstatustowear";
private static final String NEW_PREFERENCES_PATH = "/sendpreferencestowear";
public static final String BASAL_DATA_PATH = "/nightscout_watch_basal";
public static final String BOLUS_PROGRESS_PATH = "/nightscout_watch_bolusprogress";
public static final String ACTION_CONFIRMATION_REQUEST_PATH = "/nightscout_watch_actionconfirmationrequest";
@ -282,6 +284,15 @@ public class ListenerService extends WearableListenerService implements GoogleAp
messageIntent.setAction(Intent.ACTION_SEND);
messageIntent.putExtra("basals", dataMap.toBundle());
LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent);
} else if (path.equals(NEW_PREFERENCES_PATH)){
dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
if(dataMap.containsKey("wearcontrol")) {
boolean wearcontrol = dataMap.getBoolean("wearcontrol", false);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("wearcontrol", wearcontrol);
editor.commit();
}
} else {
dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
Intent messageIntent = new Intent();

View file

@ -32,8 +32,9 @@ public class MainMenuActivity extends MenuListActivity {
@Override
protected String[] getElements() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if(!BuildConfig.WEAR_CONTROL){
if(!sharedPreferences.getBoolean("wearcontrol", false)){
return new String[] {
"Settings",
"Re-Sync"};

View file

@ -37,7 +37,13 @@
</string-array>
<string name="label_xdrip">AAPS</string>
<string name="label_xdrip_large">AAPS(Large)</string>
<string name="label_xdrip_big_chart">AAPS(BigChart)</string>
<string name="label_xdrip_no_chart">AAPS(NoChart)</string>
<string name="label_xdrip_circle">AAPS(Circle)</string>
<string name="label_xdrip_activity">AAPS</string>
<string name="app_settings">AAPS Settings</string>
<string name="title_activity_bolus">BolusActivity</string>
<string name="hello_round">Hello Round World!</string>