This commit is contained in:
Milos Kozak 2019-10-01 14:56:21 +02:00
commit 20a2d84a0a
14 changed files with 67 additions and 34 deletions

View file

@ -126,6 +126,10 @@ public class SafetyPlugin extends PluginBase implements ConstraintsInterface {
if (Config.APS) {
double maxBasal = SP.getDouble(R.string.key_openapsma_max_basal, 1d);
if (maxBasal < profile.getMaxDailyBasal()) {
maxBasal = profile.getMaxDailyBasal();
absoluteRate.addReason(MainApp.gs(R.string.increasingmaxbasal), this);
}
absoluteRate.setIfSmaller(maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), maxBasal, MainApp.gs(R.string.maxvalueinpreferences)), this);
// Check percentRate but absolute rate too, because we know real current basal in pump

View file

@ -77,7 +77,7 @@ class AutomationFragment : Fragment() {
if (eventListAdapter == null) return
eventListAdapter?.notifyDataSetChanged()
val sb = StringBuilder()
for (l in AutomationPlugin.executionLog) {
for (l in AutomationPlugin.executionLog.reversed()) {
sb.append(l)
sb.append("\n")
}

View file

@ -56,6 +56,11 @@ class ChooseActionDialog : DialogFragment() {
cancel.setOnClickListener { dismiss() }
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(bundle: Bundle) {
bundle.putInt("checkedIndex", determineCheckedIndex())
}

View file

@ -58,6 +58,11 @@ class ChooseTriggerDialog : DialogFragment() {
cancel.setOnClickListener { dismiss() }
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
fun setOnClickListener(clickListener: OnClickListener) {
this.clickListener = clickListener
}

View file

@ -14,7 +14,6 @@ import kotlinx.android.synthetic.main.okcancel.*
import org.json.JSONObject
class EditActionDialog : DialogFragment() {
private var action: Action? = null
private var actionPosition: Int = -1
@ -51,6 +50,11 @@ class EditActionDialog : DialogFragment() {
cancel.setOnClickListener { dismiss() }
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
action?.let {

View file

@ -137,6 +137,11 @@ class EditEventDialog : DialogFragment() {
)
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onDestroyView() {
super.onDestroyView()
disposable.clear()

View file

@ -31,18 +31,23 @@ class EditTriggerDialog : DialogFragment() {
super.onViewCreated(view, savedInstanceState)
// display root trigger
trigger?.let { it.generateDialog(automation_layoutTrigger, fragmentManager) }
trigger?.generateDialog(automation_layoutTrigger, fragmentManager)
// OK button
ok.setOnClickListener {
dismiss()
RxBus.send(EventAutomationUpdateTrigger(trigger!!))
trigger?.let { trigger -> RxBus.send(EventAutomationUpdateTrigger(trigger)) }
}
// Cancel button
cancel.setOnClickListener { dismiss() }
}
override fun onStart() {
super.onStart()
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
trigger?.let { bundle.putString("trigger", it.toJSON()) }

View file

@ -2,7 +2,6 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="300dp"
android:padding="10dp">
<LinearLayout

View file

@ -15,7 +15,8 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/please_choose_an_action_type" />
android:text="@string/please_choose_an_action_type"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<RadioGroup
android:id="@+id/automation_radioGroup"

View file

@ -15,7 +15,8 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/please_choose_a_trigger_type" />
android:text="@string/please_choose_a_trigger_type"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<RadioGroup
android:id="@+id/automation_chooseTriggerRadioGroup"

View file

@ -15,7 +15,8 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/triggers" />
android:text="@string/triggers"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<LinearLayout
android:id="@+id/automation_layoutTrigger"

View file

@ -1584,5 +1584,6 @@
<string name="loading">Loading ...</string>
<string name="snooze">Snooze</string>
<string name="close">Close</string>
<string name="increasingmaxbasal">Increasing max basal value because setting is lower than your max basal in profile</string>
</resources>

View file

@ -156,6 +156,7 @@ public class AAPSMocker {
when(MainApp.gs(R.string.resumeloop)).thenReturn("Resume loop");
when(MainApp.gs(R.string.suspendloop)).thenReturn("Suspend loop");
when(MainApp.gs(R.string.pumpNotInitialized)).thenReturn("Pump not initialized!");
when(MainApp.gs(R.string.increasingmaxbasal)).thenReturn("Increasing max basal value because setting is lower than your max basal in profile");
}
public static MainApp mockMainApp() {

View file

@ -2,8 +2,7 @@ package info.nightscout.androidaps.plugins.constraints.safety;
import android.content.Context;
import junit.framework.Assert;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -33,11 +32,11 @@ import static org.mockito.Mockito.when;
@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, SP.class, Context.class})
public class SafetyPluginTest {
VirtualPumpPlugin pump = new VirtualPumpPlugin();
SafetyPlugin safetyPlugin;
private VirtualPumpPlugin pump = new VirtualPumpPlugin();
private SafetyPlugin safetyPlugin;
@Test
public void pumpDescriptionShouldLimitLoopInvokation() throws Exception {
public void pumpDescriptionShouldLimitLoopInvocation() {
pump.getPumpDescription().isTempBasalCapable = false;
Constraint<Boolean> c = new Constraint<>(true);
@ -53,7 +52,7 @@ public class SafetyPluginTest {
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isClosedLoopAllowed(c);
Assert.assertEquals(true, c.getReasons().contains("Running dev version. Closed loop is disabled."));
Assert.assertTrue(c.getReasons().contains("Running dev version. Closed loop is disabled."));
Assert.assertEquals(Boolean.FALSE, c.value());
}
@ -63,34 +62,34 @@ public class SafetyPluginTest {
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isClosedLoopAllowed(c);
Assert.assertEquals(true, c.getReasons().contains("Closed loop mode disabled in preferences"));
Assert.assertTrue(c.getReasons().contains("Closed loop mode disabled in preferences"));
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void notEnabledSMBInPreferencesDisablesSMB() throws Exception {
public void notEnabledSMBInPreferencesDisablesSMB() {
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true));
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isSMBModeEnabled(c);
Assert.assertEquals(true, c.getReasons().contains("SMB disabled in preferences"));
Assert.assertTrue(c.getReasons().contains("SMB disabled in preferences"));
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void openLoopPreventsSMB() throws Exception {
public void openLoopPreventsSMB() {
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(true);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(false));
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isSMBModeEnabled(c);
Assert.assertEquals(true, c.getReasons().contains("SMB not allowed in open loop mode"));
Assert.assertTrue(c.getReasons().contains("SMB not allowed in open loop mode"));
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void bgsourceShouldPreventSMBAlways() throws Exception {
public void bgSourceShouldPreventSMBAlways() {
when(ConfigBuilderPlugin.getPlugin().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin());
Constraint<Boolean> c = new Constraint<>(true);
@ -100,7 +99,7 @@ public class SafetyPluginTest {
}
@Test
public void basalRateShouldBeLimited() throws Exception {
public void basalRateShouldBeLimited() {
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);
@ -108,7 +107,7 @@ public class SafetyPluginTest {
Constraint<Double> c = new Constraint<>(Constants.REALLYHIGHBASALRATE);
safetyPlugin.applyBasalConstraints(c, AAPSMocker.getValidProfile());
Assert.assertEquals(1d, c.value());
Assert.assertEquals(1d, c.value(), 0.01d);
Assert.assertEquals("Safety: Limiting basal rate to 1.00 U/h because of max value in preferences\n" +
"Safety: Limiting basal rate to 4.00 U/h because of max basal multiplier\n" +
"Safety: Limiting basal rate to 3.00 U/h because of max daily basal multiplier\n" +
@ -118,17 +117,18 @@ public class SafetyPluginTest {
}
@Test
public void doNotAllowNegativeBasalRate() throws Exception {
public void doNotAllowNegativeBasalRate() {
when(SP.getString(R.string.key_age, "")).thenReturn("child");
Constraint<Double> d = new Constraint<>(-0.5d);
safetyPlugin.applyBasalConstraints(d, AAPSMocker.getValidProfile());
Assert.assertEquals(0d, d.value());
Assert.assertEquals("Safety: Limiting basal rate to 0.00 U/h because of it must be positive value", d.getReasons());
Assert.assertEquals(0d, d.value(), 0.01d);
Assert.assertEquals("Safety: Limiting basal rate to 0.00 U/h because of it must be positive value\n" +
"Safety: Increasing max basal value because setting is lower than your max basal in profile", d.getReasons());
}
@Test
public void percentBasalRateShouldBeLimited() throws Exception {
public void percentBasalRateShouldBeLimited() {
// 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);
@ -149,7 +149,7 @@ public class SafetyPluginTest {
}
@Test
public void doNotAllowNegativePercentBasalRate() throws Exception {
public void doNotAllowNegativePercentBasalRate() {
when(SP.getString(R.string.key_age, "")).thenReturn("child");
Constraint<Integer> i = new Constraint<>(-22);
@ -157,37 +157,38 @@ public class SafetyPluginTest {
Assert.assertEquals((Integer) 0, i.value());
Assert.assertEquals("Safety: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h\n" +
"Safety: Limiting basal rate to 0.00 U/h because of it must be positive value\n" +
"Safety: Increasing max basal value because setting is lower than your max basal in profile\n" +
"Safety: Limiting percent rate to 0% because of pump limit", i.getReasons());
Assert.assertEquals("Safety: Limiting percent rate to 0% because of pump limit", i.getMostLimitedReasons());
}
@Test
public void bolusAmountShouldBeLimited() throws Exception {
public void bolusAmountShouldBeLimited() {
when(SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d)).thenReturn(3d);
when(SP.getString(R.string.key_age, "")).thenReturn("child");
Constraint<Double> d = new Constraint<>(Constants.REALLYHIGHBOLUS);
d = safetyPlugin.applyBolusConstraints(d);
Assert.assertEquals(3d, d.value());
Assert.assertEquals(3d, d.value(), 0.01d);
Assert.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences\n" +
"Safety: Limiting bolus to 5.0 U because of hard limit", d.getReasons());
Assert.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons());
}
@Test
public void doNotAllowNegativeBolusAmount() throws Exception {
public void doNotAllowNegativeBolusAmount() {
when(SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d)).thenReturn(3d);
when(SP.getString(R.string.key_age, "")).thenReturn("child");
Constraint<Double> d = new Constraint<>(-22d);
d = safetyPlugin.applyBolusConstraints(d);
Assert.assertEquals(0d, d.value());
Assert.assertEquals(0d, d.value(), 0.01d);
Assert.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons());
Assert.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getMostLimitedReasons());
}
@Test
public void carbsAmountShouldBeLimited() throws Exception {
public void carbsAmountShouldBeLimited() {
// No limit by default
when(SP.getInt(R.string.key_treatmentssafety_maxcarbs, 48)).thenReturn(48);
@ -204,7 +205,7 @@ public class SafetyPluginTest {
}
@Test
public void iobShouldBeLimited() throws Exception {
public void iobShouldBeLimited() {
when(SP.getDouble(R.string.key_openapsma_max_iob, 1.5d)).thenReturn(1.5d);
when(SP.getString(R.string.key_age, "")).thenReturn("teenage");
OpenAPSMAPlugin.getPlugin().setPluginEnabled(PluginType.APS, true);
@ -214,7 +215,7 @@ public class SafetyPluginTest {
// Apply all limits
Constraint<Double> d = new Constraint<>(Constants.REALLYHIGHIOB);
d = safetyPlugin.applyMaxIOBConstraints(d);
Assert.assertEquals(1.5d, d.value());
Assert.assertEquals(1.5d, d.value(), 0.01d);
Assert.assertEquals("Safety: Limiting IOB to 1.5 U because of max value in preferences\n" +
"Safety: Limiting IOB to 7.0 U because of hard limit\n" +
"Safety: Limiting IOB to 7.0 U because of hard limit", d.getReasons());