diff --git a/app/src/main/java/info/nightscout/androidaps/Constants.java b/app/src/main/java/info/nightscout/androidaps/Constants.java
index d933018790..d96f432415 100644
--- a/app/src/main/java/info/nightscout/androidaps/Constants.java
+++ b/app/src/main/java/info/nightscout/androidaps/Constants.java
@@ -41,10 +41,13 @@ public class Constants {
// Temp targets
public static final int defaultActivityTTDuration = 90; // min
public static final double defaultActivityTTmgdl = 90d;
- public static final double defaultActivityTTmmol = 5d;
+ public static final double defaultActivityTTmmol = 8d;
public static final int defaultEatingSoonTTDuration = 45; // min
public static final double defaultEatingSoonTTmgdl = 140d;
- public static final double defaultEatingSoonTTmmol = 8d;
+ public static final double defaultEatingSoonTTmmol = 5d;
+ public static final int defaultHypoTTDuration = 30; // min
+ public static final double defaultHypoTTmgdl = 120d;
+ public static final double defaultHypoTTmmol = 6.5d;
//NSClientInternal
public static final int MAX_LOG_LINES = 100;
diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java
index 7dfc3c6c65..3c068b79d7 100644
--- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java
+++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java
@@ -17,7 +17,8 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
-import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
import android.widget.TextView;
import com.google.common.base.Joiner;
@@ -25,7 +26,6 @@ import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
-import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,7 +44,6 @@ import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
-import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
@@ -53,7 +52,7 @@ import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
import info.nightscout.utils.ToastUtils;
-public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
+public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener, CompoundButton.OnCheckedChangeListener {
private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class);
private NumberPicker editCarbs;
@@ -71,9 +70,10 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
private static final int FAV1_DEFAULT = 5;
private static final int FAV2_DEFAULT = 10;
private static final int FAV3_DEFAULT = 20;
- private CheckBox suspendLoopCheckbox;
- private CheckBox startActivityTTCheckbox;
- private CheckBox startEatingSoonTTCheckbox;
+ private RadioButton startActivityTTCheckbox;
+ private RadioButton startEatingSoonTTCheckbox;
+ private RadioButton startHypoTTCheckbox;
+ private boolean togglingTT;
private Integer maxCarbs;
@@ -127,7 +127,11 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt);
- startEatingSoonTTCheckbox = view.findViewById(R.id.carbs_eating_soon_tt);
+ startActivityTTCheckbox.setOnCheckedChangeListener(this);
+ startEatingSoonTTCheckbox = view.findViewById(R.id.newcarbs_eating_soon_tt);
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
+ startHypoTTCheckbox = view.findViewById(R.id.newcarbs_hypo_tt);
+ startHypoTTCheckbox.setOnCheckedChangeListener(this);
dateButton = view.findViewById(R.id.newcarbs_eventdate);
timeButton = view.findViewById(R.id.newcarb_eventtime);
@@ -139,10 +143,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
dateButton.setOnClickListener(this);
timeButton.setOnClickListener(this);
- //To be able to select only one TT at a time
- startEatingSoonTTCheckbox.setOnClickListener(this);
- startActivityTTCheckbox.setOnClickListener(this);
-
fav1Button = view.findViewById(R.id.newcarbs_plus1);
fav1Button.setOnClickListener(this);
fav1Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)));
@@ -155,8 +155,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
fav3Button.setOnClickListener(this);
fav3Button.setText(toSignedString(SP.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)));
- suspendLoopCheckbox = view.findViewById(R.id.newcarbs_suspend_loop);
-
setCancelable(true);
getDialog().setCanceledOnTouchOutside(false);
return view;
@@ -215,12 +213,84 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
validateInputs();
break;
case R.id.newcarbs_activity_tt:
- startEatingSoonTTCheckbox.setChecked(false);
- break;
- case R.id.carbs_eating_soon_tt:
+ if (togglingTT) {
+ togglingTT = false;
+ break;
+ }
+ startActivityTTCheckbox.setOnClickListener(null);
+ startActivityTTCheckbox.setOnCheckedChangeListener(null);
startActivityTTCheckbox.setChecked(false);
+ startActivityTTCheckbox.setOnCheckedChangeListener(this);
break;
+ case R.id.newcarbs_eating_soon_tt:
+ if (togglingTT) {
+ togglingTT = false;
+ break;
+ }
+ startEatingSoonTTCheckbox.setOnClickListener(null);
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
+ startEatingSoonTTCheckbox.setChecked(false);
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
+ break;
+ case R.id.newcarbs_hypo_tt:
+ if (togglingTT) {
+ togglingTT = false;
+ break;
+ }
+ startHypoTTCheckbox.setOnClickListener(null);
+ startHypoTTCheckbox.setOnCheckedChangeListener(null);
+ startHypoTTCheckbox.setChecked(false);
+ startHypoTTCheckbox.setOnCheckedChangeListener(this);
+ break;
+ }
+ }
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ // Logic to disable a selected radio when pressed. When a checked radio
+ // is pressed, no CheckChanged event is trigger, so register a Click event
+ // when checking a radio. Since Click events come after CheckChanged events,
+ // the Click event is triggered immediately after this. Thus, set toggingTT
+ // var to true, so that the first Click event fired after this is ignored.
+ // Radios remove themselves from Click events once unchecked.
+ // Since radios are not in a group, manually update their state.
+ switch (buttonView.getId()) {
+ case R.id.newcarbs_activity_tt:
+ togglingTT = true;
+ startActivityTTCheckbox.setOnClickListener(this);
+
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
+ startEatingSoonTTCheckbox.setChecked(false);
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
+
+ startHypoTTCheckbox.setOnCheckedChangeListener(null);
+ startHypoTTCheckbox.setChecked(false);
+ startHypoTTCheckbox.setOnCheckedChangeListener(this);
+ break;
+ case R.id.newcarbs_eating_soon_tt:
+ togglingTT = true;
+ startEatingSoonTTCheckbox.setOnClickListener(this);
+
+ startActivityTTCheckbox.setOnCheckedChangeListener(null);
+ startActivityTTCheckbox.setChecked(false);
+ startActivityTTCheckbox.setOnCheckedChangeListener(this);
+
+ startHypoTTCheckbox.setOnCheckedChangeListener(null);
+ startHypoTTCheckbox.setChecked(false);
+ startHypoTTCheckbox.setOnCheckedChangeListener(this);
+ break;
+ case R.id.newcarbs_hypo_tt:
+ togglingTT = true;
+ startHypoTTCheckbox.setOnClickListener(this);
+
+ startActivityTTCheckbox.setOnCheckedChangeListener(null);
+ startActivityTTCheckbox.setChecked(false);
+ startActivityTTCheckbox.setOnCheckedChangeListener(this);
+
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(null);
+ startEatingSoonTTCheckbox.setChecked(false);
+ startEatingSoonTTCheckbox.setOnCheckedChangeListener(this);
+ break;
}
}
@@ -240,9 +310,6 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
actions.add(MainApp.gs(R.string.carbs) + ": " + "" + carbsAfterConstraints + "g" + "");
if (!carbsAfterConstraints.equals(carbs))
actions.add("" + MainApp.gs(R.string.carbsconstraintapplied) + "");
- if (suspendLoopCheckbox.isChecked()) {
- actions.add(MainApp.gs(R.string.loop) + ": " + "" + MainApp.gs(R.string.suspendloopfor30min) + "");
- }
final Profile currentProfile = MainApp.getConfigBuilder().getProfile();
if (currentProfile == null)
@@ -258,6 +325,11 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl);
eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl;
+ int hypoTTDuration = SP.getInt(R.string.key_hypo_duration, Constants.defaultHypoTTDuration);
+ hypoTTDuration = hypoTTDuration > 0 ? hypoTTDuration : Constants.defaultHypoTTDuration;
+ double hypoTT = SP.getDouble(R.string.key_hypo_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl);
+ hypoTT = hypoTT > 0 ? hypoTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultHypoTTmmol : Constants.defaultHypoTTmgdl;
+
if (startActivityTTCheckbox.isChecked()) {
if (currentProfile.getUnits().equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(activityTT) + " mmol/l (" + activityTTDuration + " min)");
@@ -265,107 +337,109 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(activityTT) + " mg/dl (" + activityTTDuration + " min)");
}
- if (startEatingSoonTTCheckbox.isChecked() && !startActivityTTCheckbox.isChecked()) {
+ if (startEatingSoonTTCheckbox.isChecked()) {
if (currentProfile.getUnits().equals(Constants.MMOL)) {
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(eatingSoonTT) + " mmol/l (" + eatingSoonTTDuration + " min)");
} else
actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(eatingSoonTT) + " mg/dl (" + eatingSoonTTDuration + " min)");
-
}
+ if (startHypoTTCheckbox.isChecked()) {
+ if (currentProfile.getUnits().equals(Constants.MMOL)) {
+ actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to1Decimal(hypoTT) + " mmol/l (" + hypoTTDuration + " min)");
+ } else
+ actions.add(MainApp.gs(R.string.temptargetshort) + ": " + "" + DecimalFormatter.to0Decimal(hypoTT) + " mg/dl (" + hypoTTDuration + " min)");
+ }
+
final double finalActivityTT = activityTT;
- final double finalEatigSoonTT = eatingSoonTT;
final int finalActivityTTDuration = activityTTDuration;
+ final double finalEatigSoonTT = eatingSoonTT;
final int finalEatingSoonTTDuration = eatingSoonTTDuration;
+ final double finalHypoTT = hypoTT;
+ final int finalHypoTTDuration = hypoTTDuration;
if (!initialEventTime.equals(eventTime)) {
actions.add("Time: " + DateUtil.dateAndTimeString(eventTime));
}
+ final int finalCarbsAfterConstraints = carbsAfterConstraints;
- final int finalCarbsAfterConstraints = carbsAfterConstraints;
+ final Context context = getContext();
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context);
- final Context context = getContext();
- final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(MainApp.gs(R.string.confirmation));
+ builder.setMessage(actions.isEmpty()
+ ? MainApp.gs(R.string.no_action_selected)
+ : Html.fromHtml(Joiner.on("
").join(actions)));
+ builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
+ synchronized (builder) {
+ if (accepted) {
+ log.debug("guarding: already accepted");
+ return;
+ }
+ accepted = true;
- builder.setTitle(MainApp.gs(R.string.confirmation));
- builder.setMessage(actions.isEmpty()
- ? MainApp.gs(R.string.no_action_selected)
- : Html.fromHtml(Joiner.on("
").join(actions)));
- builder.setPositiveButton(MainApp.gs(R.string.ok), actions.isEmpty() ? null : (dialog, id) -> {
- synchronized (builder) {
- if (accepted) {
- log.debug("guarding: already accepted");
- return;
- }
- accepted = true;
+ if (startActivityTTCheckbox.isChecked()) {
+ TempTarget tempTarget = new TempTarget();
+ tempTarget.date = System.currentTimeMillis();
+ tempTarget.durationInMinutes = finalActivityTTDuration;
+ tempTarget.reason = MainApp.gs(R.string.activity);
+ tempTarget.source = Source.USER;
+ tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
+ tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
+ MainApp.getDbHelper().createOrUpdate(tempTarget);
+ } else if (startEatingSoonTTCheckbox.isChecked()) {
+ TempTarget tempTarget = new TempTarget();
+ tempTarget.date = System.currentTimeMillis();
+ tempTarget.durationInMinutes = finalEatingSoonTTDuration;
+ tempTarget.reason = MainApp.gs(R.string.eatingsoon);
+ tempTarget.source = Source.USER;
+ tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
+ tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
+ MainApp.getDbHelper().createOrUpdate(tempTarget);
+ } else if (startHypoTTCheckbox.isChecked()) {
+ TempTarget tempTarget = new TempTarget();
+ tempTarget.date = System.currentTimeMillis();
+ tempTarget.durationInMinutes = finalHypoTTDuration;
+ tempTarget.reason = MainApp.gs(R.string.hypo);
+ tempTarget.source = Source.USER;
+ tempTarget.low = Profile.toMgdl(finalHypoTT, currentProfile.getUnits());
+ tempTarget.high = Profile.toMgdl(finalHypoTT, currentProfile.getUnits());
+ MainApp.getDbHelper().createOrUpdate(tempTarget);
+ }
- if (suspendLoopCheckbox.isChecked()) {
- final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
- activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000);
- ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
+ if (finalCarbsAfterConstraints > 0) {
+ DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
+ detailedBolusInfo.date = eventTime.getTime();
+ detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
+ detailedBolusInfo.carbs = finalCarbsAfterConstraints;
+ detailedBolusInfo.context = context;
+ detailedBolusInfo.source = Source.USER;
+ if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
+ ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
@Override
public void run() {
if (!result.success) {
- ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror));
+ Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
+ i.putExtra("soundid", R.raw.boluserror);
+ i.putExtra("status", result.comment);
+ i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ MainApp.instance().startActivity(i);
}
}
});
- }
-
- if (startActivityTTCheckbox.isChecked()) {
- TempTarget tempTarget = new TempTarget();
- tempTarget.date = System.currentTimeMillis();
- tempTarget.durationInMinutes = finalActivityTTDuration;
- tempTarget.reason = MainApp.gs(R.string.activity);
- tempTarget.source = Source.USER;
- tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
- tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits());
- MainApp.getDbHelper().createOrUpdate(tempTarget);
- } else if (startEatingSoonTTCheckbox.isChecked()) {
- TempTarget tempTarget = new TempTarget();
- tempTarget.date = System.currentTimeMillis();
- tempTarget.durationInMinutes = finalEatingSoonTTDuration;
- tempTarget.reason = MainApp.gs(R.string.eatingsoon);
- tempTarget.source = Source.USER;
- tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
- tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits());
- MainApp.getDbHelper().createOrUpdate(tempTarget);
- }
-
- if (finalCarbsAfterConstraints > 0) {
- DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
- detailedBolusInfo.date = eventTime.getTime();
- detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION;
- detailedBolusInfo.carbs = finalCarbsAfterConstraints;
- detailedBolusInfo.context = context;
- detailedBolusInfo.source = Source.USER;
- if (ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) {
- ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() {
- @Override
- public void run() {
- if (!result.success) {
- Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
- i.putExtra("soundid", R.raw.boluserror);
- i.putExtra("status", result.comment);
- i.putExtra("title", MainApp.gs(R.string.treatmentdeliveryerror));
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- MainApp.instance().startActivity(i);
- }
- }
- });
- } else {
- MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
- }
+ } else {
+ MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
}
}
- });
- builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
- builder.show();
- dismiss();
+ }
+ });
+ builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
+ builder.show();
+ dismiss();
} catch (Exception e) {
log.error("Unhandled exception", e);
}
-
}
@Override
diff --git a/app/src/main/res/layout/overview_newcarbs_dialog.xml b/app/src/main/res/layout/overview_newcarbs_dialog.xml
index 64ed498e2e..25ca0d75d2 100644
--- a/app/src/main/res/layout/overview_newcarbs_dialog.xml
+++ b/app/src/main/res/layout/overview_newcarbs_dialog.xml
@@ -32,25 +32,33 @@
android:padding="5dp"
android:src="@drawable/icon_cp_bolus_carbs" />
-
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="vertical">
-
+
-
+
+
+
+
+
-
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="center_horizontal">
-
+
+
+
+
+
Use AMA autosens feature
Refresh events from NS
Eating Soon
+ Hypo
Activity
Remove record:
DanaR Stats
@@ -743,10 +744,14 @@
eatingsoon target
activity duration
activity target
+ hypo duration
+ hypo target
eatingsoon_duration
eatingsoon_target
activity_duration
activity_target
+ hypo_duration
+ hypo_target
Prime
Getting extended bolus status
Getting bolus status
@@ -988,5 +993,6 @@
Insulin On Board
Basals
No action selected, nothing will happen
+ Start Hypo TT
diff --git a/app/src/main/res/xml/pref_others.xml b/app/src/main/res/xml/pref_others.xml
index ba16f09c2f..9ecf31aca3 100644
--- a/app/src/main/res/xml/pref_others.xml
+++ b/app/src/main/res/xml/pref_others.xml
@@ -25,6 +25,16 @@
android:inputType="numberDecimal"
android:key="@string/key_activity_target"
android:title="@string/activity_target">
+
+