applyBasalPercentConstraints reactor & tests part1
This commit is contained in:
parent
ca70cbdaec
commit
e2ea44a8a8
26 changed files with 144 additions and 108 deletions
|
@ -13,7 +13,7 @@ public class Constants {
|
|||
public static final double defaultDIA = 3d;
|
||||
|
||||
public static final Double REALLYHIGHBASALRATE = 1111111d;
|
||||
public static final Integer basalPercentOnlyForCheckLimit = 10101010;
|
||||
public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111;
|
||||
public static final double bolusOnlyForCheckLimit = 10101010d;
|
||||
public static final Integer carbsOnlyForCheckLimit = 10101010;
|
||||
|
||||
|
|
|
@ -112,15 +112,14 @@ public class ConstraintChecker implements ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
Integer rateAfterConstrain = percentRate;
|
||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
|
||||
for (PluginBase p : constraintsPlugins) {
|
||||
ConstraintsInterface constrain = (ConstraintsInterface) p;
|
||||
if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue;
|
||||
rateAfterConstrain = Math.min(constrain.applyBasalPercentConstraints(percentRate), rateAfterConstrain);
|
||||
constrain.applyBasalPercentConstraints(percentRate, profile);
|
||||
}
|
||||
return rateAfterConstrain;
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ public interface ConstraintsInterface {
|
|||
|
||||
Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile);
|
||||
|
||||
Integer applyBasalPercentConstraints(Integer percentRate);
|
||||
Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile);
|
||||
|
||||
Double applyBolusConstraints(Double insulin);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public interface PumpInterface {
|
|||
PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo);
|
||||
void stopBolusDelivering();
|
||||
PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew);
|
||||
PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew);
|
||||
PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew);
|
||||
PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes);
|
||||
//some pumps might set a very short temp close to 100% as cancelling a temp can be noisy
|
||||
//when the cancel request is requested by the user (forced), the pump should always do a real cancel
|
||||
|
|
|
@ -125,7 +125,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
|||
String confirmMessage = getString(R.string.setbasalquestion);
|
||||
if (setAsPercent) {
|
||||
int basalPercentInput = SafeParse.stringToInt(basalPercent.getText());
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(basalPercentInput);
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(basalPercentInput), profile).value();
|
||||
confirmMessage += "\n" + percent + "% ";
|
||||
confirmMessage += "\n" + getString(R.string.duration) + " " + durationInMinutes + "min ?";
|
||||
if (percent != basalPercentInput)
|
||||
|
@ -162,7 +162,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi
|
|||
}
|
||||
};
|
||||
if (setAsPercent) {
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, callback);
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(finalBasalPercent, finalDurationInMinutes, true, profile, callback);
|
||||
} else {
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback);
|
||||
}
|
||||
|
|
|
@ -303,7 +303,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
|
|||
}
|
||||
};
|
||||
|
||||
Integer maxPercent = MainApp.getConstraintChecker().applyBasalPercentConstraints(Constants.basalPercentOnlyForCheckLimit);
|
||||
Integer maxPercent = 200;
|
||||
if (profile != null)
|
||||
maxPercent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE), profile).value();
|
||||
editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput);
|
||||
editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher);
|
||||
|
||||
|
|
|
@ -696,9 +696,9 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void disconnectPump(int durationInMinutes) {
|
||||
public void disconnectPump(int durationInMinutes, Profile profile) {
|
||||
getActiveLoop().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
|
||||
getCommandQueue().tempBasalPercent(0, durationInMinutes, true, new Callback() {
|
||||
getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
|
|
|
@ -351,7 +351,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
|||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.HardLimits;
|
||||
import info.nightscout.utils.Round;
|
||||
import info.nightscout.utils.SP;
|
||||
|
@ -154,49 +155,25 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
Double maxBasal = SP.getDouble(R.string.key_openapsma_max_basal, 1d);
|
||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||
|
||||
Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile == null) return percentRate;
|
||||
Double currentBasal = profile.getBasal();
|
||||
Double absoluteRate = currentBasal * ((double) percentRate.originalValue() / 100);
|
||||
|
||||
Double absoluteRate = currentBasal * ((double) percentRate / 100);
|
||||
percentRate.reason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h");
|
||||
|
||||
if (Config.logConstraintsChanges)
|
||||
log.debug("Percent rate " + percentRate + "% recalculated to " + absoluteRate + "U/h with current basal " + currentBasal + "U/h");
|
||||
Constraint<Double> absoluteConstraint = new Constraint<>(absoluteRate);
|
||||
applyBasalConstraints(absoluteConstraint, profile);
|
||||
|
||||
if (absoluteRate < 0) absoluteRate = 0d;
|
||||
|
||||
Double maxBasalMult = SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d);
|
||||
Integer maxBasalFromDaily = SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3);
|
||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
||||
Double origRate = absoluteRate;
|
||||
if (absoluteRate > maxBasal) {
|
||||
absoluteRate = maxBasal;
|
||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting rate " + origRate + " by maxBasal preference to " + absoluteRate + "U/h");
|
||||
}
|
||||
if (absoluteRate > maxBasalMult * profile.getBasal()) {
|
||||
absoluteRate = Math.floor(maxBasalMult * profile.getBasal() * 100) / 100;
|
||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting rate " + origRate + " by maxBasalMult to " + absoluteRate + "U/h");
|
||||
}
|
||||
if (absoluteRate > profile.getMaxDailyBasal() * maxBasalFromDaily) {
|
||||
absoluteRate = profile.getMaxDailyBasal() * maxBasalFromDaily;
|
||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + absoluteRate + "U/h");
|
||||
}
|
||||
|
||||
Integer percentRateAfterConst = new Double(absoluteRate / currentBasal * 100).intValue();
|
||||
Integer percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue();
|
||||
if (percentRateAfterConst < 100)
|
||||
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, 10d).intValue();
|
||||
else percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, 10d).intValue();
|
||||
|
||||
if (Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Recalculated percent rate " + percentRate + "% to " + percentRateAfterConst + "%");
|
||||
return percentRateAfterConst;
|
||||
percentRate.set(percentRateAfterConst, String.format(MainApp.gs(R.string.limitingpercentrate), percentRateAfterConst, MainApp.gs(R.string.pumplimit)));
|
||||
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -296,7 +296,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
return;
|
||||
}
|
||||
okClicked = true;
|
||||
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) {
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
|
||||
if (profile != null && (calculatedTotalInsulin > 0d || calculatedCarbs > 0d)) {
|
||||
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
||||
|
||||
String confirmMessage = getString(R.string.entertreatmentquestion);
|
||||
|
@ -341,7 +343,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
|
|||
activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
||||
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
||||
}
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, new Callback() {
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
|
|
|
@ -440,7 +440,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
if (v == apsModeView) {
|
||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
||||
final PumpDescription pumpDescription = ConfigBuilderPlugin.getActivePump().getPumpDescription();
|
||||
if (activeloop == null)
|
||||
if (activeloop == null || !MainApp.getConfigBuilder().isProfileValid("ContexMenuCreation"))
|
||||
return;
|
||||
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
|
||||
if (activeloop.isEnabled(PluginBase.LOOP)) {
|
||||
|
@ -474,6 +474,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
||||
if (profile == null)
|
||||
return true;
|
||||
final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop();
|
||||
if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) {
|
||||
activeloop.setFragmentEnabled(PluginBase.LOOP, false);
|
||||
|
@ -527,23 +530,23 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor15m))) {
|
||||
MainApp.getConfigBuilder().disconnectPump(15);
|
||||
MainApp.getConfigBuilder().disconnectPump(15, profile);
|
||||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
|
||||
MainApp.getConfigBuilder().disconnectPump(30);
|
||||
MainApp.getConfigBuilder().disconnectPump(30, profile);
|
||||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
|
||||
MainApp.getConfigBuilder().disconnectPump(60);
|
||||
MainApp.getConfigBuilder().disconnectPump(60, profile);
|
||||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
|
||||
MainApp.getConfigBuilder().disconnectPump(120);
|
||||
MainApp.getConfigBuilder().disconnectPump(120, profile);
|
||||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
|
||||
MainApp.getConfigBuilder().disconnectPump(180);
|
||||
MainApp.getConfigBuilder().disconnectPump(180, profile);
|
||||
updateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) {
|
||||
|
@ -761,7 +764,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
activeloop.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000);
|
||||
MainApp.bus().post(new EventRefreshOverview("WizardDialog"));
|
||||
}
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, new Callback() {
|
||||
ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 120, true, profile, new Callback() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!result.success) {
|
||||
|
|
|
@ -764,7 +764,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
* is or isn't running at the moment
|
||||
*/
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, final Integer durationInMinutes, boolean forceNew) {
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, final Integer durationInMinutes, Profile profile, boolean forceNew) {
|
||||
return setTempBasalPercent(percent, durationInMinutes);
|
||||
}
|
||||
|
||||
|
@ -1458,7 +1458,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,9 +214,9 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
|
|||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(percent);
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value();
|
||||
if (percent < 0) {
|
||||
result.isTempCancel = false;
|
||||
result.enacted = false;
|
||||
|
@ -291,7 +291,8 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
|
|||
result.isTempCancel = false;
|
||||
result.duration = pump.extendedBolusRemainingMinutes;
|
||||
result.absolute = pump.extendedBolusAbsoluteRate;
|
||||
if (! SP.getBoolean("danar_useextended", false)) result.bolusDelivered = pump.extendedBolusAmount;
|
||||
if (!SP.getBoolean("danar_useextended", false))
|
||||
result.bolusDelivered = pump.extendedBolusAmount;
|
||||
result.isPercent = false;
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setExtendedBolus: OK");
|
||||
|
@ -465,19 +466,14 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
|
|||
return absoluteRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
if (percentRate < 0) percentRate = 0;
|
||||
if (percentRate > getPumpDescription().maxTempPercent)
|
||||
percentRate = getPumpDescription().maxTempPercent;
|
||||
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
|
||||
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)));
|
||||
percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)));
|
||||
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBooleanExpression")
|
||||
@Override
|
||||
public Double applyBolusConstraints(Double insulin) {
|
||||
double origInsulin = insulin;
|
||||
|
|
|
@ -249,7 +249,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
|||
// Convert duration from minutes to hours
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)");
|
||||
return setTempBasalPercent(percentRate, durationInMinutes, false);
|
||||
return setTempBasalPercent(percentRate, durationInMinutes, profile, false);
|
||||
}
|
||||
if (doExtendedTemp) {
|
||||
// Check if some temp is already in progress
|
||||
|
|
|
@ -250,7 +250,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin {
|
|||
// Convert duration from minutes to hours
|
||||
if (Config.logPumpActions)
|
||||
log.debug("setTempBasalAbsolute: Setting temp basal " + percentRate + "% for " + durationInMinutes + " mins (doLowTemp || doHighTemp)");
|
||||
return setTempBasalPercent(percentRate, durationInMinutes, false);
|
||||
return setTempBasalPercent(percentRate, durationInMinutes, profile,false);
|
||||
}
|
||||
if (doExtendedTemp) {
|
||||
// Check if some temp is already in progress
|
||||
|
|
|
@ -306,16 +306,14 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
Integer origPercentRate = percentRate;
|
||||
if (percentRate < 0) percentRate = 0;
|
||||
if (percentRate > getPumpDescription().maxTempPercent)
|
||||
percentRate = getPumpDescription().maxTempPercent;
|
||||
if (!Objects.equals(percentRate, origPercentRate) && Config.logConstraintsChanges && !Objects.equals(origPercentRate, Constants.basalPercentOnlyForCheckLimit))
|
||||
log.debug("Limiting percent rate " + origPercentRate + "% to " + percentRate + "%");
|
||||
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)));
|
||||
percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)));
|
||||
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Double applyBolusConstraints(Double insulin) {
|
||||
double origInsulin = insulin;
|
||||
|
@ -586,9 +584,9 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
public synchronized PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(percent);
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value();
|
||||
if (percent < 0) {
|
||||
result.isTempCancel = false;
|
||||
result.enacted = false;
|
||||
|
|
|
@ -262,9 +262,9 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(percent);
|
||||
percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value();
|
||||
if (percent < 0) {
|
||||
result.isTempCancel = false;
|
||||
result.enacted = false;
|
||||
|
|
|
@ -22,11 +22,11 @@ import info.nightscout.androidaps.db.ExtendedBolus;
|
|||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.interfaces.Constraint;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
|
@ -65,13 +65,12 @@ import static info.nightscout.androidaps.plugins.PumpInsight.history.PumpIdCache
|
|||
|
||||
/**
|
||||
* Created by jamorham on 23/01/2018.
|
||||
*
|
||||
* <p>
|
||||
* Connects to SightRemote app service using SightParser library
|
||||
*
|
||||
* <p>
|
||||
* SightRemote and SightParser created by Tebbe Ubben
|
||||
*
|
||||
* <p>
|
||||
* Original proof of concept SightProxy by jamorham
|
||||
*
|
||||
*/
|
||||
|
||||
@SuppressWarnings("AccessStaticViaInstance")
|
||||
|
@ -394,7 +393,8 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
|
|||
for (int i = 0; i < profile.getBasalValues().length; i++) {
|
||||
Profile.BasalValue basalValue = profile.getBasalValues()[i];
|
||||
Profile.BasalValue nextValue = null;
|
||||
if (profile.getBasalValues().length > i + 1) nextValue = profile.getBasalValues()[i + 1];
|
||||
if (profile.getBasalValues().length > i + 1)
|
||||
nextValue = profile.getBasalValues()[i + 1];
|
||||
profileBlocks.add(new BRProfileBlock.ProfileBlock((((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60), Helpers.roundDouble(basalValue.value, 2)));
|
||||
log("setNewBasalProfile: " + basalValue.value + " for " + Integer.toString(((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60));
|
||||
}
|
||||
|
@ -424,12 +424,15 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
|
|||
BRProfileBlock.ProfileBlock profileBlock = profileBlocks.get(i);
|
||||
Profile.BasalValue basalValue = profile.getBasalValues()[i];
|
||||
Profile.BasalValue nextValue = null;
|
||||
if (profile.getBasalValues().length > i + 1) nextValue = profile.getBasalValues()[i + 1];
|
||||
if (profile.getBasalValues().length > i + 1)
|
||||
nextValue = profile.getBasalValues()[i + 1];
|
||||
log("isThisProfileSet - Comparing block: Pump: " + profileBlock.getAmount() + " for " + profileBlock.getDuration()
|
||||
+ " Profile: " + basalValue.value + " for " + Integer.toString(((nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) / 60));
|
||||
if (profileBlock.getDuration() * 60 != (nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds) return false;
|
||||
if (profileBlock.getDuration() * 60 != (nextValue != null ? nextValue.timeAsSeconds : 24 * 60 * 60) - basalValue.timeAsSeconds)
|
||||
return false;
|
||||
//Allow a little imprecision due to rounding errors
|
||||
if (Math.abs(profileBlock.getAmount() - Helpers.roundDouble(basalValue.value, 2)) >= 0.01D) return false;
|
||||
if (Math.abs(profileBlock.getAmount() - Helpers.roundDouble(basalValue.value, 2)) >= 0.01D)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -516,9 +519,12 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
|
|||
final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
|
||||
ActiveBolusesMessage activeBolusesMessage = (ActiveBolusesMessage) mstatus.getResponseObject();
|
||||
ActiveBolus activeBolus = null;
|
||||
if (activeBolusesMessage.getBolus1() != null && activeBolusesMessage.getBolus1().getBolusID() == bolusingEvent.bolusId) activeBolus = activeBolusesMessage.getBolus1();
|
||||
else if (activeBolusesMessage.getBolus2() != null && activeBolusesMessage.getBolus2().getBolusID() == bolusingEvent.bolusId) activeBolus = activeBolusesMessage.getBolus2();
|
||||
else if (activeBolusesMessage.getBolus3() != null && activeBolusesMessage.getBolus3().getBolusID() == bolusingEvent.bolusId) activeBolus = activeBolusesMessage.getBolus3();
|
||||
if (activeBolusesMessage.getBolus1() != null && activeBolusesMessage.getBolus1().getBolusID() == bolusingEvent.bolusId)
|
||||
activeBolus = activeBolusesMessage.getBolus1();
|
||||
else if (activeBolusesMessage.getBolus2() != null && activeBolusesMessage.getBolus2().getBolusID() == bolusingEvent.bolusId)
|
||||
activeBolus = activeBolusesMessage.getBolus2();
|
||||
else if (activeBolusesMessage.getBolus3() != null && activeBolusesMessage.getBolus3().getBolusID() == bolusingEvent.bolusId)
|
||||
activeBolus = activeBolusesMessage.getBolus3();
|
||||
if (activeBolus == null) break;
|
||||
else {
|
||||
bolusingEvent.percent = (int) (100D / activeBolus.getInitialAmount() * (activeBolus.getInitialAmount() - activeBolus.getLeftoverAmount()));
|
||||
|
@ -567,7 +573,6 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
|
|||
if (percent_amount > 250) percent_amount = 250;
|
||||
|
||||
|
||||
|
||||
final SetTBRTaskRunner task = new SetTBRTaskRunner(connector.getServiceConnector(), percent_amount, durationInMinutes);
|
||||
final UUID cmd = aSyncTaskRunner(task, "Set TBR abs: " + absoluteRate + " " + durationInMinutes + "m");
|
||||
|
||||
|
@ -611,7 +616,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
|
|||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) {
|
||||
log("Set TBR %");
|
||||
|
||||
percent = (int) Math.round(((double) percent) / 10d) * 10;
|
||||
|
@ -1117,8 +1122,11 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer applyBasalPercentConstraints(Integer percentRate) {
|
||||
return Math.min(percentRate, pumpDescription.maxTempPercent);
|
||||
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)));
|
||||
percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)));
|
||||
|
||||
return percentRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -204,7 +204,7 @@ public class MDIPlugin implements PluginBase, PumpInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) {
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
result.success = false;
|
||||
result.comment = MainApp.instance().getString(R.string.pumperror);
|
||||
|
|
|
@ -313,7 +313,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew) {
|
||||
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) {
|
||||
TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder();
|
||||
PumpEnactResult result = new PumpEnactResult();
|
||||
if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
|
||||
|
|
|
@ -208,7 +208,7 @@ public class CommandQueue {
|
|||
}
|
||||
|
||||
// returns true if command is queued
|
||||
public boolean tempBasalPercent(int percent, int durationInMinutes, boolean enforceNew, Callback callback) {
|
||||
public boolean tempBasalPercent(Integer percent, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) {
|
||||
if (isRunning(Command.CommandType.TEMPBASAL)) {
|
||||
if (callback != null)
|
||||
callback.result(executingNowError()).run();
|
||||
|
@ -218,10 +218,10 @@ public class CommandQueue {
|
|||
// remove all unfinished
|
||||
removeAll(Command.CommandType.TEMPBASAL);
|
||||
|
||||
Integer percentAfterConstraints = MainApp.getConstraintChecker().applyBasalPercentConstraints(percent);
|
||||
Integer percentAfterConstraints = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value();
|
||||
|
||||
// add new command to queue
|
||||
add(new CommandTempBasalPercent(percentAfterConstraints, durationInMinutes, enforceNew, callback));
|
||||
add(new CommandTempBasalPercent(percentAfterConstraints, durationInMinutes, enforceNew, profile, callback));
|
||||
|
||||
notifyAboutNewCommand();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
|
@ -18,18 +19,20 @@ public class CommandTempBasalPercent extends Command {
|
|||
int durationInMinutes;
|
||||
int percent;
|
||||
boolean enforceNew;
|
||||
Profile profile;
|
||||
|
||||
public CommandTempBasalPercent(int percent, int durationInMinutes, boolean enforceNew, Callback callback) {
|
||||
public CommandTempBasalPercent(int percent, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) {
|
||||
commandType = CommandType.TEMPBASAL;
|
||||
this.percent = percent;
|
||||
this.durationInMinutes = durationInMinutes;
|
||||
this.enforceNew = enforceNew;
|
||||
this.profile = profile;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setTempBasalPercent(percent, durationInMinutes, enforceNew);
|
||||
PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setTempBasalPercent(percent, durationInMinutes, profile, enforceNew);
|
||||
if (Config.logCongigBuilderActions)
|
||||
log.debug("setTempBasalPercent percent: " + percent + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted);
|
||||
if (callback != null)
|
||||
|
|
|
@ -978,5 +978,6 @@
|
|||
<string name="key_openapsma_max_iob" translatable="false">openapsma_max_iob</string>
|
||||
<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>
|
||||
</resources>
|
||||
|
||||
|
|
|
@ -38,5 +38,6 @@ public class ConstraintTest {
|
|||
d.setIfSmaller(4d, "Set 4d");
|
||||
Assert.assertEquals(4d, d.value());
|
||||
Assert.assertEquals("Set 5d\nSet 6d\nSet 4d", d.getReasons());
|
||||
Assert.assertEquals(10d, d.originalValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,6 +215,48 @@ public class ConstraintsCheckerTest {
|
|||
|
||||
}
|
||||
|
||||
// applyBasalConstraints tests
|
||||
@Test
|
||||
public void percentBasalRateShouldBeLimited() throws Exception {
|
||||
// DanaR, RS
|
||||
danaRPlugin.setFragmentEnabled(PluginBase.PUMP, true);
|
||||
danaRSPlugin.setFragmentEnabled(PluginBase.PUMP, true);
|
||||
DanaRPump.getInstance().maxBasal = 0.8d;
|
||||
|
||||
// Insight
|
||||
insightPlugin.setFragmentEnabled(PluginBase.PUMP, true);
|
||||
StatusTaskRunner.Result result = new StatusTaskRunner.Result();
|
||||
result.maximumBasalAmount = 1.1d;
|
||||
insightPlugin.setStatusResult(result);
|
||||
|
||||
|
||||
// No limit by default
|
||||
when(SP.getDouble(R.string.key_openapsma_max_basal, 1d)).thenReturn(1d);
|
||||
when(SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d)).thenReturn(4d);
|
||||
when(SP.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3d)).thenReturn(3d);
|
||||
|
||||
// Negative basal not allowed
|
||||
Constraint<Integer> i = new Constraint<>(-22);
|
||||
constraintChecker.applyBasalPercentConstraints(i, profile);
|
||||
Assert.assertEquals((Integer)0, i.value());
|
||||
Assert.assertEquals("Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h\n" + // SafetyPlugin
|
||||
"Limiting percent rate to 0% because of pump limit\n" + // SafetyPlugin
|
||||
"Limiting percent rate to 0% because of basal must be positive value\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", i.getReasons()); // InsightPlugin
|
||||
|
||||
// Apply all limits
|
||||
i = new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE);
|
||||
constraintChecker.applyBasalPercentConstraints(i, profile);
|
||||
Assert.assertEquals((Integer)100, i.value());
|
||||
Assert.assertEquals("Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h\n" + // SafetyPlugin
|
||||
"Limiting percent rate to 100% because of pump limit\n" +
|
||||
"Limiting percent rate to 200% because of pump limit\n" +
|
||||
"Limiting percent rate to 200% because of pump limit\n" +
|
||||
"Limiting percent rate to 250% because of pump limit", i.getReasons());
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void prepareMock() throws Exception {
|
||||
Locale.setDefault(new Locale("en", "US"));
|
||||
|
@ -247,6 +289,8 @@ public class ConstraintsCheckerTest {
|
|||
when(MainApp.gs(R.string.maxbasalinpreferences)).thenReturn("max basal settings in preferences");
|
||||
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.limitingpercentrate)).thenReturn("Limiting percent rate to %d%% because of %s");
|
||||
when(MainApp.gs(R.string.pumplimit)).thenReturn("pump limit");
|
||||
|
||||
PowerMockito.mockStatic(SP.class);
|
||||
// RS constructor
|
||||
|
|
|
@ -73,7 +73,7 @@ public class CommandQueueTest extends CommandQueue {
|
|||
Assert.assertEquals(1, size());
|
||||
|
||||
// add tempbasal percent. it should replace previous TEMPBASAL
|
||||
tempBasalPercent(0, 30, true, null);
|
||||
tempBasalPercent(0, 30, true, profile, null);
|
||||
Assert.assertEquals(1, size());
|
||||
|
||||
// add extended bolus
|
||||
|
@ -129,6 +129,8 @@ public class CommandQueueTest extends CommandQueue {
|
|||
when(MainApp.getConstraintChecker().applyCarbsConstraints(carbs)).thenReturn(carbs);
|
||||
Constraint<Double> rateConstraint = new Constraint<>(0d);
|
||||
when(MainApp.getConstraintChecker().applyBasalConstraints(any(), any())).thenReturn(rateConstraint);
|
||||
Constraint<Integer> percentageConstraint = new Constraint<>(0);
|
||||
when(MainApp.getConstraintChecker().applyBasalPercentConstraints(any(), any())).thenReturn(percentageConstraint);
|
||||
|
||||
PowerMockito.mockStatic(ToastUtils.class);
|
||||
Context context = mock(Context.class);
|
||||
|
|
Loading…
Reference in a new issue