applyCarbsConstraints refactor & tests

This commit is contained in:
Milos Kozak 2018-03-22 10:31:07 +01:00
parent 15158fb5ea
commit 1aba9a2564
20 changed files with 70 additions and 54 deletions

View file

@ -15,7 +15,7 @@ public class Constants {
public static final Double REALLYHIGHBASALRATE = 1111111d; public static final Double REALLYHIGHBASALRATE = 1111111d;
public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111; public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111;
public static final double REALLYHIGHBOLUS = 1111111d; public static final double REALLYHIGHBOLUS = 1111111d;
public static final Integer carbsOnlyForCheckLimit = 10101010; public static final Integer REALLYHIGHCARBS = 1111111;
public static final Integer notificationID = 556677; public static final Integer notificationID = 556677;

View file

@ -134,15 +134,14 @@ public class ConstraintChecker implements ConstraintsInterface {
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
Integer carbsAfterConstrain = carbs;
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue;
carbsAfterConstrain = Math.min(constrain.applyCarbsConstraints(carbs), carbsAfterConstrain); constrain.applyCarbsConstraints(carbs);
} }
return carbsAfterConstrain; return carbs;
} }
@Override @Override

View file

@ -23,7 +23,7 @@ public interface ConstraintsInterface {
Constraint<Double> applyBolusConstraints(Constraint<Double> insulin); Constraint<Double> applyBolusConstraints(Constraint<Double> insulin);
Integer applyCarbsConstraints(Integer carbs); Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs);
Double applyMaxIOBConstraints(Double maxIob); Double applyMaxIOBConstraints(Double maxIob);

View file

@ -272,7 +272,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
} }
}); });
Integer maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); Integer maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)).value();
editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput); editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false);

View file

@ -361,7 +361,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
return carbs; return carbs;
} }

View file

@ -134,10 +134,10 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
@Override @Override
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) { public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
absoluteRate.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbasalratio), 0d, MainApp.gs(R.string.basalmustbepositivevalue)), this); absoluteRate.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbasalratio), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this);
double maxBasal = SP.getDouble(R.string.key_openapsma_max_basal, 1d); double maxBasal = SP.getDouble(R.string.key_openapsma_max_basal, 1d);
absoluteRate.setIfSmaller(maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), maxBasal, MainApp.gs(R.string.maxbasalinpreferences)), this); absoluteRate.setIfSmaller(maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), maxBasal, MainApp.gs(R.string.maxvalueinpreferences)), this);
// Check percentRate but absolute rate too, because we know real current basal in pump // Check percentRate but absolute rate too, because we know real current basal in pump
Double maxBasalMult = SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d); Double maxBasalMult = SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d);
@ -174,7 +174,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
@Override @Override
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) { public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
insulin.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbolus), 0d, MainApp.gs(R.string.bolusmustbepositivevalue)), this); insulin.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbolus), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this);
Double maxBolus = SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d); Double maxBolus = SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d);
insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this); insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this);
@ -184,15 +184,12 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
try { carbs.setIfGreater(0, String.format(MainApp.gs(R.string.limitingcarbs), 0, MainApp.gs(R.string.itmustbepositivevalue)), this);
Integer maxCarbs = SP.getInt("treatmentssafety_maxcarbs", 48);
Integer maxCarbs = SP.getInt(R.string.key_treatmentssafety_maxcarbs, 48);
carbs.setIfSmaller(maxCarbs, String.format(MainApp.gs(R.string.limitingcarbs), maxCarbs, MainApp.gs(R.string.maxvalueinpreferences)), this);
if (carbs < 0) carbs = 0;
if (carbs > maxCarbs) carbs = maxCarbs;
} catch (Exception e) {
carbs = 0;
}
return carbs; return carbs;
} }

View file

@ -43,6 +43,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
@ -120,7 +121,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)).value();
editCarbs = view.findViewById(R.id.newcarb_carbsamount); editCarbs = view.findViewById(R.id.newcarb_carbsamount);
@ -303,7 +304,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
okClicked = true; okClicked = true;
try { try {
final Integer carbs = SafeParse.stringToInt(editCarbs.getText()); final Integer carbs = SafeParse.stringToInt(editCarbs.getText());
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(carbs); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
List<String> actions = new LinkedList<>(); List<String> actions = new LinkedList<>();
if (carbs > 0) if (carbs > 0)

View file

@ -96,7 +96,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)).value();
maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value(); maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount); editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount);
@ -130,7 +130,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "<br/>"; String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "<br/>";
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(carbs); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
if (insulin > 0) { if (insulin > 0) {
confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>"; confirmMessage += MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>";

View file

@ -237,7 +237,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE); superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE);
Integer maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); Integer maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)).value();
Double maxCorrection = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value(); Double maxCorrection = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher); editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher);
@ -305,7 +305,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
String confirmMessage = getString(R.string.entertreatmentquestion); String confirmMessage = getString(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(calculatedCarbs); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(calculatedCarbs)).value();
confirmMessage += "<br/>" + getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U" + "</font>"; confirmMessage += "<br/>" + getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U" + "</font>";
confirmMessage += "<br/>" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g"; confirmMessage += "<br/>" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
@ -467,7 +467,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied)); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));
return; return;
} }
Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(c_carbs); Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value();
if (c_carbs - carbsAfterConstraint != 0) { if (c_carbs - carbsAfterConstraint != 0) {
editCarbs.setValue(0d); editCarbs.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied)); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied));

View file

@ -728,7 +728,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
String confirmMessage = getString(R.string.entertreatmentquestion); String confirmMessage = getString(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(wizard.calculatedTotalInsulin)).value(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(wizard.calculatedTotalInsulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(quickWizardEntry.carbs()); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value();
confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U"; confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U";
confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g"; confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";

View file

@ -1468,7 +1468,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
return carbs; return carbs;
} }

View file

@ -467,7 +467,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
@Override @Override
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) { public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.basalmustbepositivevalue)), this); percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this);
percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this);
return percentRate; return percentRate;
@ -481,7 +481,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
return carbs; return carbs;
} }

View file

@ -306,7 +306,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
@Override @Override
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) { public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.basalmustbepositivevalue)), this); percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this);
percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this);
return percentRate; return percentRate;
@ -321,7 +321,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
return carbs; return carbs;
} }

View file

@ -1123,7 +1123,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
@Override @Override
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) { public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.basalmustbepositivevalue)), this); percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this);
percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this);
return percentRate; return percentRate;
@ -1137,7 +1137,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
} }
@Override @Override
public Integer applyCarbsConstraints(Integer carbs) { public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
return carbs; return carbs;
} }

View file

@ -116,7 +116,7 @@ public class ActionStringHandler {
double insulin = SafeParse.stringToDouble(act[1]); double insulin = SafeParse.stringToDouble(act[1]);
int carbs = SafeParse.stringToInt(act[2]); int carbs = SafeParse.stringToInt(act[2]);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(carbs); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value();
rMessage += MainApp.instance().getString(R.string.bolus) + ": " + insulinAfterConstraints + "U\n"; rMessage += MainApp.instance().getString(R.string.bolus) + ": " + insulinAfterConstraints + "U\n";
rMessage += MainApp.instance().getString(R.string.carbs) + ": " + carbsAfterConstraints + "g"; rMessage += MainApp.instance().getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
@ -180,7 +180,7 @@ public class ActionStringHandler {
} else if ("wizard".equals(act[0])) { } else if ("wizard".equals(act[0])) {
////////////////////////////////////////////// WIZARD ////////////////////////////////////////////// WIZARD
Integer carbsBeforeConstraints = SafeParse.stringToInt(act[1]); Integer carbsBeforeConstraints = SafeParse.stringToInt(act[1]);
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(carbsBeforeConstraints); Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbsBeforeConstraints)).value();
if (carbsAfterConstraints - carbsBeforeConstraints != 0) { if (carbsAfterConstraints - carbsBeforeConstraints != 0) {
sendError("Carb constraint violation!"); sendError("Carb constraint violation!");

View file

@ -167,7 +167,7 @@ public class CommandQueue {
// apply constraints // apply constraints
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
detailedBolusInfo.carbs = MainApp.getConstraintChecker().applyCarbsConstraints((int) detailedBolusInfo.carbs); detailedBolusInfo.carbs = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>((int) detailedBolusInfo.carbs)).value();
// add new command to queue // add new command to queue
if (detailedBolusInfo.isSMB) { if (detailedBolusInfo.isSMB) {

View file

@ -971,9 +971,7 @@
<string name="key_openapsma_max_basal" translatable="false">openapsma_max_basal</string> <string name="key_openapsma_max_basal" translatable="false">openapsma_max_basal</string>
<string name="key_openapsama_current_basal_safety_multiplier" translatable="false">openapsama_current_basal_safety_multiplier</string> <string name="key_openapsama_current_basal_safety_multiplier" translatable="false">openapsama_current_basal_safety_multiplier</string>
<string name="key_openapsama_max_daily_safety_multiplier" translatable="false">openapsama_max_daily_safety_multiplier</string> <string name="key_openapsama_max_daily_safety_multiplier" translatable="false">openapsama_max_daily_safety_multiplier</string>
<string name="basalmustbepositivevalue">basal must be positive value</string> <string name="itmustbepositivevalue">it must be positive value</string>
<string name="bolusmustbepositivevalue">bolus must be positive value</string>
<string name="maxbasalinpreferences">max basal settings in preferences</string>
<string name="maxbasalmultiplier">max basal multiplier</string> <string name="maxbasalmultiplier">max basal multiplier</string>
<string name="maxdailybasalmultiplier">max daily basal multiplier</string> <string name="maxdailybasalmultiplier">max daily basal multiplier</string>
<string name="key_openapsma_max_iob" translatable="false">openapsma_max_iob</string> <string name="key_openapsma_max_iob" translatable="false">openapsma_max_iob</string>
@ -982,7 +980,9 @@
<string name="limitingpercentrate" formatted="false">Limiting percent rate to %d%% because of %s</string> <string name="limitingpercentrate" formatted="false">Limiting percent rate to %d%% because of %s</string>
<string name="key_treatmentssafety_maxbolus" translatable="false">treatmentssafety_maxbolus</string> <string name="key_treatmentssafety_maxbolus" translatable="false">treatmentssafety_maxbolus</string>
<string name="limitingbolus">Limiting bolus to %.1f U because of %s</string> <string name="limitingbolus">Limiting bolus to %.1f U because of %s</string>
<string name="limitingcarbs">Limiting carbs to %d g because of %s</string>
<string name="maxvalueinpreferences">max value in preferences</string> <string name="maxvalueinpreferences">max value in preferences</string>
<string name="hardlimit">hard limit</string> <string name="hardlimit">hard limit</string>
<string name="key_treatmentssafety_maxcarbs">treatmentssafety_maxcarbs</string>
</resources> </resources>

View file

@ -12,7 +12,7 @@
</EditTextPreference> </EditTextPreference>
<EditTextPreference <EditTextPreference
android:title="@string/treatmentssafety_maxcarbs_title" android:title="@string/treatmentssafety_maxcarbs_title"
android:key="treatmentssafety_maxcarbs" android:key="@string/key_treatmentssafety_maxcarbs"
android:defaultValue="48" android:defaultValue="48"
android:inputType="numberDecimal"> android:inputType="numberDecimal">
</EditTextPreference> </EditTextPreference>

View file

@ -200,13 +200,13 @@ public class ConstraintsCheckerTest {
Constraint<Double> d = new Constraint<>(-0.5d); Constraint<Double> d = new Constraint<>(-0.5d);
constraintChecker.applyBasalConstraints(d, profile); constraintChecker.applyBasalConstraints(d, profile);
Assert.assertEquals(0d, d.value()); Assert.assertEquals(0d, d.value());
Assert.assertEquals("SafetyPlugin: Limiting basal rate to 0.00 U/h because of basal must be positive value", d.getReasons()); Assert.assertEquals("SafetyPlugin: Limiting basal rate to 0.00 U/h because of it must be positive value", d.getReasons());
// Apply all limits // Apply all limits
d = new Constraint<>(Constants.REALLYHIGHBASALRATE); d = new Constraint<>(Constants.REALLYHIGHBASALRATE);
constraintChecker.applyBasalConstraints(d, profile); constraintChecker.applyBasalConstraints(d, profile);
Assert.assertEquals(0.8d, d.value()); Assert.assertEquals(0.8d, d.value());
Assert.assertEquals("SafetyPlugin: Limiting basal rate to 1.00 U/h because of max basal settings in preferences\n" + Assert.assertEquals("SafetyPlugin: Limiting basal rate to 1.00 U/h because of max value in preferences\n" +
"SafetyPlugin: Limiting basal rate to 4.00 U/h because of max basal multiplier\n" + "SafetyPlugin: Limiting basal rate to 4.00 U/h because of max basal multiplier\n" +
"SafetyPlugin: Limiting basal rate to 3.00 U/h because of max daily basal multiplier\n" + "SafetyPlugin: Limiting basal rate to 3.00 U/h because of max daily basal multiplier\n" +
"DanaRPlugin: Limiting basal rate to 0.80 U/h because of pump limit\n" + "DanaRPlugin: Limiting basal rate to 0.80 U/h because of pump limit\n" +
@ -240,18 +240,18 @@ public class ConstraintsCheckerTest {
constraintChecker.applyBasalPercentConstraints(i, profile); constraintChecker.applyBasalPercentConstraints(i, profile);
Assert.assertEquals((Integer)0, i.value()); Assert.assertEquals((Integer)0, i.value());
Assert.assertEquals("SafetyPlugin: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h\n" + Assert.assertEquals("SafetyPlugin: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h\n" +
"SafetyPlugin: Limiting basal rate to 0.00 U/h because of basal must be positive value\n" + "SafetyPlugin: Limiting basal rate to 0.00 U/h because of it must be positive value\n" +
"SafetyPlugin: Limiting percent rate to 0% because of pump limit\n" + "SafetyPlugin: Limiting percent rate to 0% because of pump limit\n" +
"DanaRPlugin: Limiting percent rate to 0% because of basal must be positive value\n" + "DanaRPlugin: Limiting percent rate to 0% because of it must be positive value\n" +
"DanaRSPlugin: Limiting percent rate to 0% because of basal must be positive value\n" + "DanaRSPlugin: Limiting percent rate to 0% because of it must be positive value\n" +
"InsightPumpPlugin: Limiting percent rate to 0% because of basal must be positive value", i.getReasons()); "InsightPumpPlugin: Limiting percent rate to 0% because of it must be positive value", i.getReasons());
// Apply all limits // Apply all limits
i = new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE); i = new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE);
constraintChecker.applyBasalPercentConstraints(i, profile); constraintChecker.applyBasalPercentConstraints(i, profile);
Assert.assertEquals((Integer)100, i.value()); Assert.assertEquals((Integer)100, i.value());
Assert.assertEquals("SafetyPlugin: Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h\n" + Assert.assertEquals("SafetyPlugin: Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h\n" +
"SafetyPlugin: Limiting basal rate to 1.00 U/h because of max basal settings in preferences\n" + "SafetyPlugin: Limiting basal rate to 1.00 U/h because of max value in preferences\n" +
"SafetyPlugin: Limiting basal rate to 4.00 U/h because of max basal multiplier\n" + "SafetyPlugin: Limiting basal rate to 4.00 U/h because of max basal multiplier\n" +
"SafetyPlugin: Limiting basal rate to 3.00 U/h because of max daily basal multiplier\n" + "SafetyPlugin: Limiting basal rate to 3.00 U/h because of max daily basal multiplier\n" +
"SafetyPlugin: Limiting percent rate to 100% because of pump limit\n" + "SafetyPlugin: Limiting percent rate to 100% because of pump limit\n" +
@ -284,7 +284,7 @@ public class ConstraintsCheckerTest {
Constraint<Double> d = new Constraint<>(-22d); Constraint<Double> d = new Constraint<>(-22d);
constraintChecker.applyBolusConstraints(d); constraintChecker.applyBolusConstraints(d);
Assert.assertEquals(0d, d.value()); Assert.assertEquals(0d, d.value());
Assert.assertEquals("SafetyPlugin: Limiting bolus to 0.0 U because of bolus must be positive value", d.getReasons()); Assert.assertEquals("SafetyPlugin: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons());
// Apply all limits // Apply all limits
d = new Constraint<>(Constants.REALLYHIGHBOLUS); d = new Constraint<>(Constants.REALLYHIGHBOLUS);
@ -298,6 +298,25 @@ public class ConstraintsCheckerTest {
} }
// applyCarbsConstraints tests
@Test
public void carbsAmountShouldBeLimited() throws Exception {
// No limit by default
when(SP.getInt(R.string.key_treatmentssafety_maxcarbs, 48)).thenReturn(48);
// Negative basal not allowed
Constraint<Integer> i = new Constraint<>(-22);
constraintChecker.applyCarbsConstraints(i);
Assert.assertEquals((Integer) 0, i.value());
Assert.assertEquals("SafetyPlugin: Limiting carbs to 0 g because of it must be positive value", i.getReasons());
// Apply all limits
i = new Constraint<>(Constants.REALLYHIGHCARBS);
constraintChecker.applyCarbsConstraints(i);
Assert.assertEquals((Integer) 48, i.value());
Assert.assertEquals("SafetyPlugin: Limiting carbs to 48 g because of max value in preferences", i.getReasons());
}
@Before @Before
public void prepareMock() throws Exception { public void prepareMock() throws Exception {
Locale.setDefault(new Locale("en", "US")); Locale.setDefault(new Locale("en", "US"));
@ -326,17 +345,16 @@ public class ConstraintsCheckerTest {
when(MainApp.gs(R.string.smbdisabledinpreferences)).thenReturn("SMB disabled in preferences"); when(MainApp.gs(R.string.smbdisabledinpreferences)).thenReturn("SMB disabled in preferences");
when(MainApp.gs(R.string.limitingbasalratio)).thenReturn("Limiting basal rate to %.2f U/h because of %s"); when(MainApp.gs(R.string.limitingbasalratio)).thenReturn("Limiting basal rate to %.2f U/h because of %s");
when(MainApp.gs(R.string.pumplimit)).thenReturn("pump limit"); when(MainApp.gs(R.string.pumplimit)).thenReturn("pump limit");
when(MainApp.gs(R.string.basalmustbepositivevalue)).thenReturn("basal must be positive value"); when(MainApp.gs(R.string.itmustbepositivevalue)).thenReturn("it must be positive value");
when(MainApp.gs(R.string.maxbasalinpreferences)).thenReturn("max basal settings in preferences"); when(MainApp.gs(R.string.maxvalueinpreferences)).thenReturn("max value in preferences");
when(MainApp.gs(R.string.maxbasalmultiplier)).thenReturn("max basal multiplier"); when(MainApp.gs(R.string.maxbasalmultiplier)).thenReturn("max basal multiplier");
when(MainApp.gs(R.string.maxdailybasalmultiplier)).thenReturn("max daily basal multiplier"); when(MainApp.gs(R.string.maxdailybasalmultiplier)).thenReturn("max daily basal multiplier");
when(MainApp.gs(R.string.limitingpercentrate)).thenReturn("Limiting percent rate to %d%% because of %s"); when(MainApp.gs(R.string.limitingpercentrate)).thenReturn("Limiting percent rate to %d%% because of %s");
when(MainApp.gs(R.string.pumplimit)).thenReturn("pump limit"); when(MainApp.gs(R.string.pumplimit)).thenReturn("pump limit");
when(MainApp.gs(R.string.limitingbolus)).thenReturn("Limiting bolus to %.1f U because of %s"); when(MainApp.gs(R.string.limitingbolus)).thenReturn("Limiting bolus to %.1f U because of %s");
when(MainApp.gs(R.string.bolusmustbepositivevalue)).thenReturn("bolus must be positive value");
when(MainApp.gs(R.string.maxvalueinpreferences)).thenReturn("max value in preferences");
when(MainApp.gs(R.string.hardlimit)).thenReturn("hard limit"); when(MainApp.gs(R.string.hardlimit)).thenReturn("hard limit");
when(MainApp.gs(R.string.key_child)).thenReturn("child"); when(MainApp.gs(R.string.key_child)).thenReturn("child");
when(MainApp.gs(R.string.limitingcarbs)).thenReturn("Limiting carbs to %d g because of %s");
PowerMockito.mockStatic(SP.class); PowerMockito.mockStatic(SP.class);
// RS constructor // RS constructor

View file

@ -127,7 +127,8 @@ public class CommandQueueTest extends CommandQueue {
when(MainApp.instance()).thenReturn(mainApp); when(MainApp.instance()).thenReturn(mainApp);
Constraint<Double> bolusConstraint = new Constraint<>(0d); Constraint<Double> bolusConstraint = new Constraint<>(0d);
when(MainApp.getConstraintChecker().applyBolusConstraints(any())).thenReturn(bolusConstraint); when(MainApp.getConstraintChecker().applyBolusConstraints(any())).thenReturn(bolusConstraint);
when(MainApp.getConstraintChecker().applyCarbsConstraints(carbs)).thenReturn(carbs); Constraint<Integer> carbsConstraint = new Constraint<>(0);
when(MainApp.getConstraintChecker().applyCarbsConstraints(any())).thenReturn(carbsConstraint);
Constraint<Double> rateConstraint = new Constraint<>(0d); Constraint<Double> rateConstraint = new Constraint<>(0d);
when(MainApp.getConstraintChecker().applyBasalConstraints(any(), any())).thenReturn(rateConstraint); when(MainApp.getConstraintChecker().applyBasalConstraints(any(), any())).thenReturn(rateConstraint);
Constraint<Integer> percentageConstraint = new Constraint<>(0); Constraint<Integer> percentageConstraint = new Constraint<>(0);