applyBolusConstraints refactor & tests

This commit is contained in:
Milos Kozak 2018-03-21 23:01:30 +01:00
parent c68ab9f1ca
commit 15158fb5ea
32 changed files with 123 additions and 86 deletions

View file

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

View file

@ -123,15 +123,14 @@ public class ConstraintChecker implements ConstraintsInterface {
}
@Override
public Double applyBolusConstraints(Double insulin) {
Double insulinAfterConstrain = insulin;
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue;
insulinAfterConstrain = Math.min(constrain.applyBolusConstraints(insulin), insulinAfterConstrain);
constrain.applyBolusConstraints(insulin);
}
return insulinAfterConstrain;
return insulin;
}
@Override

View file

@ -21,7 +21,7 @@ public interface ConstraintsInterface {
Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile);
Double applyBolusConstraints(Double insulin);
Constraint<Double> applyBolusConstraints(Constraint<Double> insulin);
Integer applyCarbsConstraints(Integer carbs);

View file

@ -26,6 +26,7 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
@ -60,7 +61,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Double maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
Double maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false);
@ -138,7 +139,7 @@ public class FillDialog extends DialogFragment implements OnClickListener {
String confirmMessage = getString(R.string.fillwarning) + "\n";
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
confirmMessage += getString(R.string.bolus) + ": " + insulinAfterConstraints + "U";
if (insulinAfterConstraints - insulin != 0)
confirmMessage += "\n" + getString(R.string.constraintapllied);

View file

@ -20,6 +20,7 @@ import java.text.DecimalFormat;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback;
@ -43,7 +44,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false);
Double maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
Double maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin);
editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false);
@ -70,7 +71,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli
String confirmMessage = getString(R.string.setextendedbolusquestion);
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
Double insulinAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
confirmMessage += " " + insulinAfterConstraint + " U ";
confirmMessage += getString(R.string.duration) + " " + durationInMinutes + "min ?";
if (insulinAfterConstraint - insulin != 0d)

View file

@ -276,7 +276,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false);
Double maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
Double maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editInsulin = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_insulininput);
editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false);

View file

@ -356,7 +356,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
}
@Override
public Double applyBolusConstraints(Double insulin) {
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
return insulin;
}

View file

@ -173,16 +173,13 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
}
@Override
public Double applyBolusConstraints(Double insulin) {
try {
Double maxBolus = SP.getDouble("treatmentssafety_maxbolus", 3d);
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
insulin.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbolus), 0d, MainApp.gs(R.string.bolusmustbepositivevalue)), this);
if (insulin < 0) insulin = 0d;
if (insulin > maxBolus) insulin = maxBolus;
} catch (Exception e) {
insulin = 0d;
}
if (insulin > HardLimits.maxBolus()) insulin = HardLimits.maxBolus();
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(HardLimits.maxBolus(), String.format(MainApp.gs(R.string.limitingbolus), HardLimits.maxBolus(), MainApp.gs(R.string.hardlimit)), this);
return insulin;
}

View file

@ -296,7 +296,8 @@ public class LoopPlugin implements PluginBase {
final APSResult resultAfterConstraints = result.clone();
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
resultAfterConstraints.rate = MainApp.getConstraintChecker().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value();
resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smb);
resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb);
resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value();
// safety check for multiple SMBs
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime();

View file

@ -44,6 +44,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil;
@ -119,7 +120,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount);
@ -223,7 +224,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
try {
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
List<String> actions = new LinkedList<>();
if (insulin > 0) {

View file

@ -31,6 +31,7 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.FabricPrivacy;
@ -96,7 +97,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
maxInsulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount);
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount);
@ -128,7 +129,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene
String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "<br/>";
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(carbs);
if (insulin > 0) {

View file

@ -52,6 +52,7 @@ import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.EventFeatureRunning;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
@ -237,7 +238,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE);
Integer maxCarbs = MainApp.getConstraintChecker().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit);
Double maxCorrection = MainApp.getConstraintChecker().applyBolusConstraints(Constants.bolusOnlyForCheckLimit);
Double maxCorrection = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)).value();
editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher);
editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
@ -303,7 +304,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
String confirmMessage = getString(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(calculatedTotalInsulin);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(calculatedCarbs);
confirmMessage += "<br/>" + getString(R.string.bolus) + ": " + "<font color='" + MainApp.sResources.getColor(R.color.bolus) + "'>" + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U" + "</font>";
@ -460,7 +461,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double c_bg = SafeParse.stringToDouble(editBg.getText());
Integer c_carbs = SafeParse.stringToInt(editCarbs.getText());
Double c_correction = SafeParse.stringToDouble(editCorr.getText());
Double corrAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(c_correction);
Double corrAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value();
if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
editCorr.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied));

View file

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

View file

@ -1463,7 +1463,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
}
@Override
public Double applyBolusConstraints(Double insulin) {
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
return insulin;
}

View file

@ -263,7 +263,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
@Override
public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
insulin = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
// needs to be rounded
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep);
@ -474,15 +474,9 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
}
@Override
public Double applyBolusConstraints(Double insulin) {
double origInsulin = insulin;
if (pump != null) {
if (insulin > pump.maxBolus) {
insulin = pump.maxBolus;
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
}
}
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
if (pump != null)
insulin.setIfSmaller(pump.maxBolus, String.format(MainApp.gs(R.string.limitingbolus), pump.maxBolus, MainApp.gs(R.string.pumplimit)), this);
return insulin;
}

View file

@ -132,7 +132,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(detailedBolusInfo.insulin);
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
Treatment t = new Treatment();
t.isSMB = detailedBolusInfo.isSMB;

View file

@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.utils.HardLimits;
public class MsgBolusStart extends MessageBase {
@ -18,9 +19,7 @@ public class MsgBolusStart extends MessageBase {
this();
// HARDCODED LIMIT
amount = MainApp.getConstraintChecker().applyBolusConstraints(amount);
if (amount < 0) amount = 0d;
if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus();
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
AddParamInt((int) (amount * 100));

View file

@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.utils.HardLimits;
public class MsgBolusStartWithSpeed extends MessageBase {
@ -18,9 +19,7 @@ public class MsgBolusStartWithSpeed extends MessageBase {
this();
// HARDCODED LIMIT
amount = MainApp.getConstraintChecker().applyBolusConstraints(amount);
if (amount < 0) amount = 0d;
if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus();
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
AddParamInt((int) (amount * 100));
AddParamByte((byte) speed);

View file

@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.utils.HardLimits;
public class MsgSetExtendedBolusStart extends MessageBase {
@ -20,9 +21,7 @@ public class MsgSetExtendedBolusStart extends MessageBase {
// HARDCODED LIMITS
if (halfhours < 1) halfhours = 1;
if (halfhours > 16) halfhours = 16;
amount = MainApp.getConstraintChecker().applyBolusConstraints(amount);
if (amount < 0d) amount = 0d;
if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus();
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
AddParamInt((int) (amount * 100));
AddParamByte(halfhours);

View file

@ -133,7 +133,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(detailedBolusInfo.insulin);
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
Treatment t = new Treatment();
t.isSMB = detailedBolusInfo.isSMB;

View file

@ -314,15 +314,9 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
@Override
public Double applyBolusConstraints(Double insulin) {
double origInsulin = insulin;
if (pump != null) {
if (insulin > pump.maxBolus) {
insulin = pump.maxBolus;
if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit)
log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U");
}
}
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
if (pump != null)
insulin.setIfSmaller(pump.maxBolus, String.format(MainApp.gs(R.string.limitingbolus), pump.maxBolus, MainApp.gs(R.string.pumplimit)), this);
return insulin;
}
@ -441,7 +435,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
@Override
public synchronized PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(detailedBolusInfo.insulin);
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0);
int speed = 12;
@ -660,7 +654,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
@Override
public synchronized PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) {
insulin = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
// needs to be rounded
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep);

View file

@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.utils.HardLimits;
public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet {
@ -27,9 +28,7 @@ public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet {
this();
// HARDCODED LIMIT
amount = MainApp.getConstraintChecker().applyBolusConstraints(amount);
if (amount < 0) amount = 0d;
if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus();
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
this.amount = amount;
this.speed = speed;

View file

@ -122,7 +122,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
// Pump interface
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(detailedBolusInfo.insulin);
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
// v2 stores end time for bolus, we need to adjust time
// default delivery speed is 12 sec/U

View file

@ -1130,8 +1130,10 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
}
@Override
public Double applyBolusConstraints(Double insulin) {
return Math.min(insulin, statusResult != null ? statusResult.maximumBolusAmount : 0);
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
if (statusResult != null)
insulin.setIfSmaller(statusResult.maximumBolusAmount, String.format(MainApp.gs(R.string.limitingbolus), statusResult.maximumBolusAmount, MainApp.gs(R.string.pumplimit)), this);
return insulin;
}
@Override

View file

@ -450,7 +450,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date()));
} else if (splited.length > 1) {
amount = SafeParse.stringToDouble(splited[1]);
amount = MainApp.getConstraintChecker().applyBolusConstraints(amount);
amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
if (amount > 0d && remoteCommandsAllowed) {
passCode = generatePasscode();
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_bolusreplywithcode), amount, passCode);

View file

@ -25,6 +25,7 @@ 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.Constraint;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog;
@ -92,7 +93,7 @@ public class ActionStringHandler {
} else {
return;
}
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(amount);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
rMessage += MainApp.instance().getString(R.string.primefill) + ": " + insulinAfterConstraints + "U";
if (insulinAfterConstraints - amount != 0)
rMessage += "\n" + MainApp.instance().getString(R.string.constraintapllied);
@ -103,7 +104,7 @@ public class ActionStringHandler {
////////////////////////////////////////////// PRIME/FILL
double amount = SafeParse.stringToDouble(act[1]);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(amount);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
rMessage += MainApp.instance().getString(R.string.primefill) + ": " + insulinAfterConstraints + "U";
if (insulinAfterConstraints - amount != 0)
rMessage += "\n" + MainApp.instance().getString(R.string.constraintapllied);
@ -114,7 +115,7 @@ public class ActionStringHandler {
////////////////////////////////////////////// BOLUS
double insulin = SafeParse.stringToDouble(act[1]);
int carbs = SafeParse.stringToInt(act[2]);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(carbs);
rMessage += MainApp.instance().getString(R.string.bolus) + ": " + insulinAfterConstraints + "U\n";
rMessage += MainApp.instance().getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
@ -207,7 +208,7 @@ public class ActionStringHandler {
BolusWizard bolusWizard = new BolusWizard();
bolusWizard.doCalc(profile, null, carbsAfterConstraints, 0d, useBG ? bgReading.valueToUnits(profile.getUnits()) : 0d, 0d, percentage, useBolusIOB, useBasalIOB, false, false);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(bolusWizard.calculatedTotalInsulin);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(bolusWizard.calculatedTotalInsulin)).value();
if (insulinAfterConstraints - bolusWizard.calculatedTotalInsulin != 0) {
sendError("Insulin contraint violation!" +
"\nCannot deliver " + format.format(bolusWizard.calculatedTotalInsulin) + "!");
@ -534,7 +535,7 @@ public class ActionStringHandler {
if ("fill".equals(act[0])) {
Double amount = SafeParse.stringToDouble(act[1]);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(amount);
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value();
if (amount - insulinAfterConstraints != 0) {
ToastUtils.showToastInUiThread(MainApp.instance(), "aborting: previously applied constraint changed");
sendError("aborting: previously applied constraint changed");

View file

@ -166,7 +166,7 @@ public class CommandQueue {
removeAll(type);
// apply constraints
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(detailedBolusInfo.insulin);
detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
detailedBolusInfo.carbs = MainApp.getConstraintChecker().applyCarbsConstraints((int) detailedBolusInfo.carbs);
// add new command to queue
@ -236,7 +236,7 @@ public class CommandQueue {
return false;
}
Double rateAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(insulin);
Double rateAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
// remove all unfinished
removeAll(Command.CommandType.EXTENDEDBOLUS);

View file

@ -49,13 +49,13 @@ public class HardLimits {
String sp_age = SP.getString(R.string.key_age, "");
int age;
if (sp_age.equals(MainApp.sResources.getString(R.string.key_child)))
if (sp_age.equals(MainApp.gs(R.string.key_child)))
age = CHILD;
else if (sp_age.equals(MainApp.sResources.getString(R.string.key_teenage)))
else if (sp_age.equals(MainApp.gs(R.string.key_teenage)))
age = TEENAGE;
else if (sp_age.equals(MainApp.sResources.getString(R.string.key_adult)))
else if (sp_age.equals(MainApp.gs(R.string.key_adult)))
age = ADULT;
else if (sp_age.equals(MainApp.sResources.getString(R.string.key_resistantadult)))
else if (sp_age.equals(MainApp.gs(R.string.key_resistantadult)))
age = RESISTANTADULT;
else age = ADULT;
@ -88,9 +88,9 @@ public class HardLimits {
if (newvalue < lowLimit || newvalue > highLimit) {
newvalue = Math.max(newvalue, lowLimit);
newvalue = Math.min(newvalue, highLimit);
String msg = String.format(MainApp.sResources.getString(R.string.valueoutofrange), valueName);
String msg = String.format(MainApp.gs(R.string.valueoutofrange), valueName);
msg += ".\n";
msg += String.format(MainApp.sResources.getString(R.string.valuelimitedto), value, newvalue);
msg += String.format(MainApp.gs(R.string.valuelimitedto), value, newvalue);
log.error(msg);
NSUpload.uploadError(msg);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error);

View file

@ -972,6 +972,7 @@
<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="basalmustbepositivevalue">basal 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="maxdailybasalmultiplier">max daily basal multiplier</string>
@ -979,5 +980,9 @@
<string name="smb_frequency_exceeded">A bolus was delivered within the last 3 minutes, skipping SMB</string>
<string name="basal_set_correctly">Basal set correctly</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="limitingbolus">Limiting bolus to %.1f U because of %s</string>
<string name="maxvalueinpreferences">max value in preferences</string>
<string name="hardlimit">hard limit</string>
</resources>

View file

@ -6,7 +6,7 @@
<EditTextPreference
android:title="@string/treatmentssafety_maxbolus_title"
android:key="treatmentssafety_maxbolus"
android:key="@string/key_treatmentssafety_maxbolus"
android:defaultValue="3"
android:inputType="numberDecimal">
</EditTextPreference>

View file

@ -244,7 +244,7 @@ public class ConstraintsCheckerTest {
"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" +
"DanaRSPlugin: Limiting percent rate to 0% because of basal must be positive value\n" +
"InsightPumpPlugin: Limiting percent rate to 0% because of basal must be positive value", i.getReasons()); // InsightPlugin
"InsightPumpPlugin: Limiting percent rate to 0% because of basal must be positive value", i.getReasons());
// Apply all limits
i = new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE);
@ -261,6 +261,43 @@ public class ConstraintsCheckerTest {
}
// applyBolusConstraints tests
@Test
public void bolusAmountShouldBeLimited() throws Exception {
// DanaR, RS
danaRPlugin.setFragmentEnabled(PluginBase.PUMP, true);
danaRSPlugin.setFragmentEnabled(PluginBase.PUMP, true);
DanaRPump.getInstance().maxBolus = 6d;
// Insight
insightPlugin.setFragmentEnabled(PluginBase.PUMP, true);
StatusTaskRunner.Result result = new StatusTaskRunner.Result();
result.maximumBolusAmount = 7d;
insightPlugin.setStatusResult(result);
// No limit by default
when(SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d)).thenReturn(3d);
when(SP.getString(R.string.key_age, "")).thenReturn("child");
// Negative basal not allowed
Constraint<Double> d = new Constraint<>(-22d);
constraintChecker.applyBolusConstraints(d);
Assert.assertEquals(0d, d.value());
Assert.assertEquals("SafetyPlugin: Limiting bolus to 0.0 U because of bolus must be positive value", d.getReasons());
// Apply all limits
d = new Constraint<>(Constants.REALLYHIGHBOLUS);
constraintChecker.applyBolusConstraints(d);
Assert.assertEquals(3d, d.value());
Assert.assertEquals("SafetyPlugin: Limiting bolus to 3.0 U because of max value in preferences\n" +
"SafetyPlugin: Limiting bolus to 5.0 U because of hard limit\n" +
"DanaRPlugin: Limiting bolus to 6.0 U because of pump limit\n" +
"DanaRSPlugin: Limiting bolus to 6.0 U because of pump limit\n" +
"InsightPumpPlugin: Limiting bolus to 7.0 U because of pump limit", d.getReasons());
}
@Before
public void prepareMock() throws Exception {
Locale.setDefault(new Locale("en", "US"));
@ -295,6 +332,11 @@ public class ConstraintsCheckerTest {
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.pumplimit)).thenReturn("pump limit");
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.key_child)).thenReturn("child");
PowerMockito.mockStatic(SP.class);
// RS constructor

View file

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