SafetyPlugin -> kt

This commit is contained in:
Milos Kozak 2021-02-15 00:57:45 +01:00
parent c099bad8af
commit 1ef8629f57
2 changed files with 195 additions and 289 deletions

View file

@ -1,289 +0,0 @@
package info.nightscout.androidaps.plugins.constraints.safety;
import androidx.annotation.NonNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.HardLimits;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
@Singleton
public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
private final SP sp;
private final RxBusWrapper rxBus;
private final ConstraintChecker constraintChecker;
private final OpenAPSAMAPlugin openAPSAMAPlugin;
private final OpenAPSSMBPlugin openAPSSMBPlugin;
private final SensitivityOref1Plugin sensitivityOref1Plugin;
private final ActivePluginProvider activePlugin;
private final HardLimits hardLimits;
private final BuildHelper buildHelper;
private final TreatmentsPlugin treatmentsPlugin;
private final Config config;
@Inject
public SafetyPlugin(
HasAndroidInjector injector,
AAPSLogger aapsLogger,
ResourceHelper resourceHelper,
SP sp,
RxBusWrapper rxBus,
ConstraintChecker constraintChecker,
OpenAPSAMAPlugin openAPSAMAPlugin,
OpenAPSSMBPlugin openAPSSMBPlugin,
SensitivityOref1Plugin sensitivityOref1Plugin,
ActivePluginProvider activePlugin,
HardLimits hardLimits,
BuildHelper buildHelper,
TreatmentsPlugin treatmentsPlugin,
Config config
) {
super(new PluginDescription()
.mainType(PluginType.CONSTRAINTS)
.neverVisible(true)
.alwaysEnabled(true)
.showInList(false)
.pluginName(R.string.safety)
.preferencesId(R.xml.pref_safety),
aapsLogger, resourceHelper, injector
);
this.sp = sp;
this.rxBus = rxBus;
this.constraintChecker = constraintChecker;
this.openAPSAMAPlugin = openAPSAMAPlugin;
this.openAPSSMBPlugin = openAPSSMBPlugin;
this.sensitivityOref1Plugin = sensitivityOref1Plugin;
this.activePlugin = activePlugin;
this.hardLimits = hardLimits;
this.buildHelper = buildHelper;
this.treatmentsPlugin = treatmentsPlugin;
this.config = config;
}
/**
* Constraints interface
**/
@NonNull @Override
public Constraint<Boolean> isLoopInvocationAllowed(@NonNull Constraint<Boolean> value) {
if (!activePlugin.getActivePump().getPumpDescription().isTempBasalCapable)
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.pumpisnottempbasalcapable), this);
return value;
}
@NonNull @Override
public Constraint<Boolean> isClosedLoopAllowed(@NonNull Constraint<Boolean> value) {
String mode = sp.getString(R.string.key_aps_mode, "open");
if ((mode.equals("open")))
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.closedmodedisabledinpreferences), this);
if (!buildHelper.isEngineeringModeOrRelease()) {
if (value.value()) {
Notification n = new Notification(Notification.TOAST_ALARM, getResourceHelper().gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL);
rxBus.send(new EventNewNotification(n));
}
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.closed_loop_disabled_on_dev_branch), this);
}
PumpInterface pump = activePlugin.getActivePump();
if (!pump.isFakingTempsByExtendedBoluses() && treatmentsPlugin.isInHistoryExtendedBoluslInProgress()) {
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.closed_loop_disabled_with_eb), this);
}
return value;
}
@NonNull @Override
public Constraint<Boolean> isAutosensModeEnabled(@NonNull Constraint<Boolean> value) {
boolean enabled = sp.getBoolean(R.string.key_openapsama_useautosens, false);
if (!enabled)
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.autosensdisabledinpreferences), this);
return value;
}
@NonNull @Override
public Constraint<Boolean> isSMBModeEnabled(@NonNull Constraint<Boolean> value) {
boolean enabled = sp.getBoolean(R.string.key_use_smb, false);
if (!enabled)
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.smbdisabledinpreferences), this);
Constraint<Boolean> closedLoop = constraintChecker.isClosedLoopAllowed();
if (!closedLoop.value())
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.smbnotallowedinopenloopmode), this);
return value;
}
@NonNull @Override
public Constraint<Boolean> isUAMEnabled(@NonNull Constraint<Boolean> value) {
boolean enabled = sp.getBoolean(R.string.key_use_uam, false);
if (!enabled)
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.uamdisabledinpreferences), this);
boolean oref1Enabled = sensitivityOref1Plugin.isEnabled(PluginType.SENSITIVITY);
if (!oref1Enabled)
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.uamdisabledoref1notselected), this);
return value;
}
@NonNull @Override
public Constraint<Boolean> isAdvancedFilteringEnabled(@NonNull Constraint<Boolean> value) {
BgSourceInterface bgSource = activePlugin.getActiveBgSource();
if (!bgSource.advancedFilteringSupported())
value.set(getAapsLogger(), false, getResourceHelper().gs(R.string.smbalwaysdisabled), this);
return value;
}
@NonNull @Override
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, @NonNull Profile profile) {
absoluteRate.setIfGreater(getAapsLogger(), 0d, String.format(getResourceHelper().gs(R.string.limitingbasalratio), 0d, getResourceHelper().gs(R.string.itmustbepositivevalue)), this);
if (config.getAPS()) {
double maxBasal = sp.getDouble(R.string.key_openapsma_max_basal, 1d);
if (maxBasal < profile.getMaxDailyBasal()) {
maxBasal = profile.getMaxDailyBasal();
absoluteRate.addReason(getResourceHelper().gs(R.string.increasingmaxbasal), this);
}
absoluteRate.setIfSmaller(getAapsLogger(), maxBasal, String.format(getResourceHelper().gs(R.string.limitingbasalratio), maxBasal, getResourceHelper().gs(R.string.maxvalueinpreferences)), this);
// 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 maxFromBasalMult = Math.floor(maxBasalMult * profile.getBasal() * 100) / 100;
absoluteRate.setIfSmaller(getAapsLogger(), maxFromBasalMult, String.format(getResourceHelper().gs(R.string.limitingbasalratio), maxFromBasalMult, getResourceHelper().gs(R.string.maxbasalmultiplier)), this);
double maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3d);
double maxFromDaily = Math.floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100;
absoluteRate.setIfSmaller(getAapsLogger(), maxFromDaily, String.format(getResourceHelper().gs(R.string.limitingbasalratio), maxFromDaily, getResourceHelper().gs(R.string.maxdailybasalmultiplier)), this);
}
absoluteRate.setIfSmaller(getAapsLogger(), hardLimits.maxBasal(), String.format(getResourceHelper().gs(R.string.limitingbasalratio), hardLimits.maxBasal(), getResourceHelper().gs(R.string.hardlimit)), this);
PumpInterface pump = activePlugin.getActivePump();
// check for pump max
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
absoluteRate.setIfSmaller(getAapsLogger(), pumpLimit, String.format(getResourceHelper().gs(R.string.limitingbasalratio), pumpLimit, getResourceHelper().gs(R.string.pumplimit)), this);
}
// do rounding
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
absoluteRate.set(getAapsLogger(), Round.roundTo(absoluteRate.value(), pump.getPumpDescription().tempAbsoluteStep));
}
return absoluteRate;
}
@NonNull @Override
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, Profile profile) {
Double currentBasal = profile.getBasal();
double absoluteRate = currentBasal * ((double) percentRate.originalValue() / 100);
percentRate.addReason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h", this);
Constraint<Double> absoluteConstraint = new Constraint<>(absoluteRate);
applyBasalConstraints(absoluteConstraint, profile);
percentRate.copyReasons(absoluteConstraint);
PumpInterface pump = activePlugin.getActivePump();
int percentRateAfterConst = Double.valueOf(absoluteConstraint.value() / currentBasal * 100).intValue();
if (percentRateAfterConst < 100)
percentRateAfterConst = Round.ceilTo((double) percentRateAfterConst, (double) pump.getPumpDescription().tempPercentStep).intValue();
else
percentRateAfterConst = Round.floorTo((double) percentRateAfterConst, (double) pump.getPumpDescription().tempPercentStep).intValue();
percentRate.set(getAapsLogger(), percentRateAfterConst, String.format(getResourceHelper().gs(R.string.limitingpercentrate), percentRateAfterConst, getResourceHelper().gs(R.string.pumplimit)), this);
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) {
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
percentRate.setIfSmaller(getAapsLogger(), (int) pumpLimit, String.format(getResourceHelper().gs(R.string.limitingbasalratio), pumpLimit, getResourceHelper().gs(R.string.pumplimit)), this);
}
return percentRate;
}
@NonNull @Override
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
insulin.setIfGreater(getAapsLogger(), 0d, String.format(getResourceHelper().gs(R.string.limitingbolus), 0d, getResourceHelper().gs(R.string.itmustbepositivevalue)), this);
Double maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3d);
insulin.setIfSmaller(getAapsLogger(), maxBolus, String.format(getResourceHelper().gs(R.string.limitingbolus), maxBolus, getResourceHelper().gs(R.string.maxvalueinpreferences)), this);
insulin.setIfSmaller(getAapsLogger(), hardLimits.maxBolus(), String.format(getResourceHelper().gs(R.string.limitingbolus), hardLimits.maxBolus(), getResourceHelper().gs(R.string.hardlimit)), this);
PumpInterface pump = activePlugin.getActivePump();
double rounded = pump.getPumpDescription().pumpType.determineCorrectBolusSize(insulin.value());
insulin.setIfDifferent(getAapsLogger(), rounded, getResourceHelper().gs(R.string.pumplimit), this);
return insulin;
}
@NonNull @Override
public Constraint<Double> applyExtendedBolusConstraints(Constraint<Double> insulin) {
insulin.setIfGreater(getAapsLogger(), 0d, String.format(getResourceHelper().gs(R.string.limitingextendedbolus), 0d, getResourceHelper().gs(R.string.itmustbepositivevalue)), this);
Double maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3d);
insulin.setIfSmaller(getAapsLogger(), maxBolus, String.format(getResourceHelper().gs(R.string.limitingextendedbolus), maxBolus, getResourceHelper().gs(R.string.maxvalueinpreferences)), this);
insulin.setIfSmaller(getAapsLogger(), hardLimits.maxBolus(), String.format(getResourceHelper().gs(R.string.limitingextendedbolus), hardLimits.maxBolus(), getResourceHelper().gs(R.string.hardlimit)), this);
PumpInterface pump = activePlugin.getActivePump();
double rounded = pump.getPumpDescription().pumpType.determineCorrectExtendedBolusSize(insulin.value());
insulin.setIfDifferent(getAapsLogger(), rounded, getResourceHelper().gs(R.string.pumplimit), this);
return insulin;
}
@NonNull @Override
public Constraint<Integer> applyCarbsConstraints(Constraint<Integer> carbs) {
carbs.setIfGreater(getAapsLogger(), 0, String.format(getResourceHelper().gs(R.string.limitingcarbs), 0, getResourceHelper().gs(R.string.itmustbepositivevalue)), this);
Integer maxCarbs = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48);
carbs.setIfSmaller(getAapsLogger(), maxCarbs, String.format(getResourceHelper().gs(R.string.limitingcarbs), maxCarbs, getResourceHelper().gs(R.string.maxvalueinpreferences)), this);
return carbs;
}
@NonNull @Override
public Constraint<Double> applyMaxIOBConstraints(@NonNull Constraint<Double> maxIob) {
double maxIobPref;
String apsmode = sp.getString(R.string.key_aps_mode, "open");
if (openAPSSMBPlugin.isEnabled(PluginType.APS))
maxIobPref = sp.getDouble(R.string.key_openapssmb_max_iob, 3d);
else
maxIobPref = sp.getDouble(R.string.key_openapsma_max_iob, 1.5d);
maxIob.setIfSmaller(getAapsLogger(), maxIobPref, String.format(getResourceHelper().gs(R.string.limitingiob), maxIobPref, getResourceHelper().gs(R.string.maxvalueinpreferences)), this);
if (openAPSAMAPlugin.isEnabled(PluginType.APS))
maxIob.setIfSmaller(getAapsLogger(), hardLimits.maxIobAMA(), String.format(getResourceHelper().gs(R.string.limitingiob), hardLimits.maxIobAMA(), getResourceHelper().gs(R.string.hardlimit)), this);
if (openAPSSMBPlugin.isEnabled(PluginType.APS))
maxIob.setIfSmaller(getAapsLogger(), hardLimits.maxIobSMB(), String.format(getResourceHelper().gs(R.string.limitingiob), hardLimits.maxIobSMB(), getResourceHelper().gs(R.string.hardlimit)), this);
if ((apsmode.equals("lgs")))
maxIob.setIfSmaller(getAapsLogger(), hardLimits.getMAXIOB_LGS(), String.format(getResourceHelper().gs(R.string.limitingiob), hardLimits.getMAXIOB_LGS(), getResourceHelper().gs(R.string.lowglucosesuspend)), this);
return maxIob;
}
}

View file

@ -0,0 +1,195 @@
package info.nightscout.androidaps.plugins.constraints.safety
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DecimalFormatter
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.Round
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.floor
@Singleton
class SafetyPlugin @Inject constructor(
injector: HasAndroidInjector,
aapsLogger: AAPSLogger,
resourceHelper: ResourceHelper,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val constraintChecker: ConstraintChecker,
private val openAPSAMAPlugin: OpenAPSAMAPlugin,
private val openAPSSMBPlugin: OpenAPSSMBPlugin,
private val sensitivityOref1Plugin: SensitivityOref1Plugin,
private val activePlugin: ActivePluginProvider,
private val hardLimits: HardLimits,
private val buildHelper: BuildHelper,
private val treatmentsPlugin: TreatmentsPlugin,
private val config: Config
) : PluginBase(PluginDescription()
.mainType(PluginType.CONSTRAINTS)
.neverVisible(true)
.alwaysEnabled(true)
.showInList(false)
.pluginName(R.string.safety)
.preferencesId(R.xml.pref_safety),
aapsLogger, resourceHelper, injector
), ConstraintsInterface {
/**
* Constraints interface
*/
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
if (!activePlugin.activePump.pumpDescription.isTempBasalCapable) value[aapsLogger, false, resourceHelper.gs(R.string.pumpisnottempbasalcapable)] = this
return value
}
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
val mode = sp.getString(R.string.key_aps_mode, "open")
if (mode == "open") value[aapsLogger, false, resourceHelper.gs(R.string.closedmodedisabledinpreferences)] = this
if (!buildHelper.isEngineeringModeOrRelease()) {
if (value.value()) {
val n = Notification(Notification.TOAST_ALARM, resourceHelper.gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL)
rxBus.send(EventNewNotification(n))
}
value[aapsLogger, false, resourceHelper.gs(R.string.closed_loop_disabled_on_dev_branch)] = this
}
val pump = activePlugin.activePump
if (!pump.isFakingTempsByExtendedBoluses && treatmentsPlugin.isInHistoryExtendedBoluslInProgress) {
value[aapsLogger, false, resourceHelper.gs(R.string.closed_loop_disabled_with_eb)] = this
}
return value
}
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
val enabled = sp.getBoolean(R.string.key_openapsama_useautosens, false)
if (!enabled) value[aapsLogger, false, resourceHelper.gs(R.string.autosensdisabledinpreferences)] = this
return value
}
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
val enabled = sp.getBoolean(R.string.key_use_smb, false)
if (!enabled) value[aapsLogger, false, resourceHelper.gs(R.string.smbdisabledinpreferences)] = this
val closedLoop = constraintChecker.isClosedLoopAllowed()
if (!closedLoop.value()) value[aapsLogger, false, resourceHelper.gs(R.string.smbnotallowedinopenloopmode)] = this
return value
}
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
val enabled = sp.getBoolean(R.string.key_use_uam, false)
if (!enabled) value[aapsLogger, false, resourceHelper.gs(R.string.uamdisabledinpreferences)] = this
val oref1Enabled = sensitivityOref1Plugin.isEnabled(PluginType.SENSITIVITY)
if (!oref1Enabled) value[aapsLogger, false, resourceHelper.gs(R.string.uamdisabledoref1notselected)] = this
return value
}
override fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
val bgSource = activePlugin.activeBgSource
if (!bgSource.advancedFilteringSupported()) value[aapsLogger, false, resourceHelper.gs(R.string.smbalwaysdisabled)] = this
return value
}
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
absoluteRate.setIfGreater(aapsLogger, 0.0, String.format(resourceHelper.gs(R.string.limitingbasalratio), 0.0, resourceHelper.gs(R.string.itmustbepositivevalue)), this)
if (config.APS) {
var maxBasal = sp.getDouble(R.string.key_openapsma_max_basal, 1.0)
if (maxBasal < profile.maxDailyBasal) {
maxBasal = profile.maxDailyBasal
absoluteRate.addReason(resourceHelper.gs(R.string.increasingmaxbasal), this)
}
absoluteRate.setIfSmaller(aapsLogger, maxBasal, String.format(resourceHelper.gs(R.string.limitingbasalratio), maxBasal, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
// Check percentRate but absolute rate too, because we know real current basal in pump
val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.basal * 100) / 100
absoluteRate.setIfSmaller(aapsLogger, maxFromBasalMultiplier, String.format(resourceHelper.gs(R.string.limitingbasalratio), maxFromBasalMultiplier, resourceHelper.gs(R.string.maxbasalmultiplier)), this)
val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0)
val maxFromDaily = floor(profile.maxDailyBasal * maxBasalFromDaily * 100) / 100
absoluteRate.setIfSmaller(aapsLogger, maxFromDaily, String.format(resourceHelper.gs(R.string.limitingbasalratio), maxFromDaily, resourceHelper.gs(R.string.maxdailybasalmultiplier)), this)
}
absoluteRate.setIfSmaller(aapsLogger, hardLimits.maxBasal(), String.format(resourceHelper.gs(R.string.limitingbasalratio), hardLimits.maxBasal(), resourceHelper.gs(R.string.hardlimit)), this)
val pump = activePlugin.activePump
// check for pump max
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose
absoluteRate.setIfSmaller(aapsLogger, pumpLimit, String.format(resourceHelper.gs(R.string.limitingbasalratio), pumpLimit, resourceHelper.gs(R.string.pumplimit)), this)
}
// do rounding
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
absoluteRate[aapsLogger] = Round.roundTo(absoluteRate.value(), pump.pumpDescription.tempAbsoluteStep)
}
return absoluteRate
}
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
val currentBasal = profile.basal
val absoluteRate = currentBasal * (percentRate.originalValue().toDouble() / 100)
percentRate.addReason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h", this)
val absoluteConstraint = Constraint(absoluteRate)
applyBasalConstraints(absoluteConstraint, profile)
percentRate.copyReasons(absoluteConstraint)
val pump = activePlugin.activePump
var percentRateAfterConst = java.lang.Double.valueOf(absoluteConstraint.value() / currentBasal * 100).toInt()
percentRateAfterConst = if (percentRateAfterConst < 100) Round.ceilTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt() else Round.floorTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt()
percentRate[aapsLogger, percentRateAfterConst, String.format(resourceHelper.gs(R.string.limitingpercentrate), percentRateAfterConst, resourceHelper.gs(R.string.pumplimit))] = this
if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT) {
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose
percentRate.setIfSmaller(aapsLogger, pumpLimit.toInt(), String.format(resourceHelper.gs(R.string.limitingbasalratio), pumpLimit, resourceHelper.gs(R.string.pumplimit)), this)
}
return percentRate
}
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
insulin.setIfGreater(aapsLogger, 0.0, String.format(resourceHelper.gs(R.string.limitingbolus), 0.0, resourceHelper.gs(R.string.itmustbepositivevalue)), this)
val maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0)
insulin.setIfSmaller(aapsLogger, maxBolus, String.format(resourceHelper.gs(R.string.limitingbolus), maxBolus, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
insulin.setIfSmaller(aapsLogger, hardLimits.maxBolus(), String.format(resourceHelper.gs(R.string.limitingbolus), hardLimits.maxBolus(), resourceHelper.gs(R.string.hardlimit)), this)
val pump = activePlugin.activePump
val rounded = pump.pumpDescription.pumpType.determineCorrectBolusSize(insulin.value())
insulin.setIfDifferent(aapsLogger, rounded, resourceHelper.gs(R.string.pumplimit), this)
return insulin
}
override fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
insulin.setIfGreater(aapsLogger, 0.0, String.format(resourceHelper.gs(R.string.limitingextendedbolus), 0.0, resourceHelper.gs(R.string.itmustbepositivevalue)), this)
val maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0)
insulin.setIfSmaller(aapsLogger, maxBolus, String.format(resourceHelper.gs(R.string.limitingextendedbolus), maxBolus, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
insulin.setIfSmaller(aapsLogger, hardLimits.maxBolus(), String.format(resourceHelper.gs(R.string.limitingextendedbolus), hardLimits.maxBolus(), resourceHelper.gs(R.string.hardlimit)), this)
val pump = activePlugin.activePump
val rounded = pump.pumpDescription.pumpType.determineCorrectExtendedBolusSize(insulin.value())
insulin.setIfDifferent(aapsLogger, rounded, resourceHelper.gs(R.string.pumplimit), this)
return insulin
}
override fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> {
carbs.setIfGreater(aapsLogger, 0, String.format(resourceHelper.gs(R.string.limitingcarbs), 0, resourceHelper.gs(R.string.itmustbepositivevalue)), this)
val maxCarbs = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48)
carbs.setIfSmaller(aapsLogger, maxCarbs, String.format(resourceHelper.gs(R.string.limitingcarbs), maxCarbs, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
return carbs
}
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
val apsMode = sp.getString(R.string.key_aps_mode, "open")
val maxIobPref: Double = if (openAPSSMBPlugin.isEnabled(PluginType.APS)) sp.getDouble(R.string.key_openapssmb_max_iob, 3.0) else sp.getDouble(R.string.key_openapsma_max_iob, 1.5)
maxIob.setIfSmaller(aapsLogger, maxIobPref, String.format(resourceHelper.gs(R.string.limitingiob), maxIobPref, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
if (openAPSAMAPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobAMA(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobAMA(), resourceHelper.gs(R.string.hardlimit)), this)
if (openAPSSMBPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobSMB(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobSMB(), resourceHelper.gs(R.string.hardlimit)), this)
if (apsMode == "lgs") maxIob.setIfSmaller(aapsLogger, hardLimits.MAXIOB_LGS, String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.MAXIOB_LGS, resourceHelper.gs(R.string.lowglucosesuspend)), this)
return maxIob
}
}