limitRunningLoop constraint

This commit is contained in:
Milos Kozak 2018-03-19 13:11:25 +01:00
parent f413c005f6
commit b0a9f678f0
17 changed files with 252 additions and 38 deletions

View file

@ -1,13 +1,13 @@
package info.nightscout.androidaps.interfaces;
import info.nightscout.androidaps.plugins.Loop.APSResult;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
/**
* Created by mike on 15.06.2016.
*/
public interface ConstraintsInterface {
boolean isLoopEnabled();
void limitRunningLoop(BooleanConstraint value);
boolean isClosedModeEnabled();

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.interfaces.constrains;
/**
* Created by mike on 19.03.2018.
*/
public class BooleanConstraint extends Constraint {
boolean value;
public BooleanConstraint(boolean value) {
this.value = value;
}
public boolean get() {
return value;
}
public BooleanConstraint set(boolean value) {
this.value = value;
return this;
}
public BooleanConstraint set(boolean value, String reason) {
this.value = value;
reason(reason);
return this;
}
}

View file

@ -0,0 +1,27 @@
package info.nightscout.androidaps.interfaces.constrains;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mike on 19.03.2018.
*/
public class Constraint {
List<String> reasons = new ArrayList<>();
public Constraint reason(String reason) {
reasons.add(reason);
return this;
}
public String getReasons() {
StringBuilder sb = new StringBuilder();
int count = 0;
for (String r: reasons) {
if (count++ != 0) sb.append("\n");
sb.append(r);
}
return sb.toString();
}
}

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.interfaces.constrains;
/**
* Created by mike on 19.03.2018.
*/
public class DoubleConstraint extends Constraint{
double value;
public DoubleConstraint(double value) {
this.value = value;
}
public Double getDouble() {
return value;
}
public DoubleConstraint set(double value) {
this.value = value;
return this;
}
public DoubleConstraint set(double value, String reason) {
this.value = value;
reason(reason);
return this;
}
}

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.interfaces.constrains;
/**
* Created by mike on 19.03.2018.
*/
public class IntegerConstraint extends Constraint {
int value;
public IntegerConstraint(int value) {
this.value = value;
}
public int getInteger() {
return value;
}
public IntegerConstraint set(int value) {
this.value = value;
return this;
}
public IntegerConstraint set(int value, String reason) {
this.value = value;
reason(reason);
return this;
}
}

View file

@ -4,8 +4,6 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -33,6 +31,7 @@ import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppInitialized;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
@ -43,7 +42,6 @@ import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.plugins.Loop.APSResult;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.queue.Callback;
@ -451,16 +449,14 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr
* Constraints interface
**/
@Override
public boolean isLoopEnabled() {
boolean result = true;
public void limitRunningLoop(BooleanConstraint value) {
ArrayList<PluginBase> constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue;
result = result && constrain.isLoopEnabled();
constrain.limitRunningLoop(value);
}
return result;
}
@Override

View file

@ -10,12 +10,12 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
@ -294,8 +294,9 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface {
* Constraints interface
**/
@Override
public boolean isLoopEnabled() {
return objectives.get(0).started.getTime() > 0;
public void limitRunningLoop(BooleanConstraint value) {
if (objectives.get(0).started.getTime() == 0)
value.set(false, MainApp.gs(R.string.objective1notstarted));
}
@Override

View file

@ -11,6 +11,7 @@ import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
@ -93,8 +94,9 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface {
}
@Override
public boolean isLoopEnabled() {
return ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable;
public void limitRunningLoop(BooleanConstraint value) {
if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable)
value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable));
}
/**

View file

@ -23,11 +23,10 @@ import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
@ -260,10 +259,13 @@ public class LoopPlugin implements PluginBase {
try {
if (Config.logFunctionCalls)
log.debug("invoke from " + initiator);
ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder();
if (!constraintsInterface.isLoopEnabled()) {
log.debug(MainApp.sResources.getString(R.string.loopdisabled));
MainApp.bus().post(new EventLoopSetLastRunGui(MainApp.sResources.getString(R.string.loopdisabled)));
BooleanConstraint loopEnabled = new BooleanConstraint(true);
MainApp.getConfigBuilder().limitRunningLoop(loopEnabled);
if (!loopEnabled.get()) {
String message = MainApp.sResources.getString(R.string.loopdisabled) + "\n" + loopEnabled.getReasons();
log.debug(message);
MainApp.bus().post(new EventLoopSetLastRunGui(message));
return;
}
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
@ -297,8 +299,8 @@ public class LoopPlugin implements PluginBase {
// check rate for constrais
final APSResult resultAfterConstraints = result.clone();
resultAfterConstraints.rate = constraintsInterface.applyBasalConstraints(resultAfterConstraints.rate);
resultAfterConstraints.smb = constraintsInterface.applyBolusConstraints(resultAfterConstraints.smb);
resultAfterConstraints.rate = MainApp.getConfigBuilder().applyBasalConstraints(resultAfterConstraints.rate);
resultAfterConstraints.smb = MainApp.getConfigBuilder().applyBolusConstraints(resultAfterConstraints.smb);
// safety check for multiple SMBs
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime();
@ -329,7 +331,7 @@ public class LoopPlugin implements PluginBase {
return;
}
if (constraintsInterface.isClosedModeEnabled()) {
if (MainApp.getConfigBuilder().isClosedModeEnabled()) {
if (result.isChangeRequested()) {
final PumpEnactResult waiting = new PumpEnactResult();
waiting.queued = true;

View file

@ -4,7 +4,6 @@ import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import org.json.JSONObject;
@ -29,6 +28,7 @@ import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpDescription;
@ -1407,8 +1407,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
private boolean validBasalRateProfileSelectedOnPump = true;
@Override
public boolean isLoopEnabled() {
return validBasalRateProfileSelectedOnPump;
public void limitRunningLoop(BooleanConstraint value) {
if (!validBasalRateProfileSelectedOnPump)
value.set(false, MainApp.gs(R.string.novalidbasalrate));
}
@Override

View file

@ -19,6 +19,7 @@ import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.DanaRInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
@ -436,8 +437,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface,
*/
@Override
public boolean isLoopEnabled() {
return true;
public void limitRunningLoop(BooleanConstraint value) {
}
@Override

View file

@ -30,6 +30,7 @@ import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.DanaRInterface;
import info.nightscout.androidaps.interfaces.PluginBase;
@ -274,8 +275,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface,
// Constraints interface
@Override
public boolean isLoopEnabled() {
return true;
public void limitRunningLoop(BooleanConstraint value) {
}
@Override

View file

@ -1,10 +1,5 @@
package info.nightscout.androidaps.plugins.PumpInsight;
import android.os.Handler;
import android.util.Log;
import com.j256.ormlite.stmt.query.In;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
@ -27,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.constrains.BooleanConstraint;
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.plugins.Overview.events.EventDismissBolusprogressIfRunning;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
@ -1085,8 +1080,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
// Constraints
@Override
public boolean isLoopEnabled() {
return true;
public void limitRunningLoop(BooleanConstraint value){
}
@Override

View file

@ -1011,5 +1011,8 @@
<string name="profileswitch_ismissing">ProfileSwitch missing. Please do a profile switch or press \"Activate Profile\" in the LocalProfile.</string>
<string name="combo_bolus_count">Bolus count</string>
<string name="combo_tbr_count">TBR count</string>
<string name="objective1notstarted">Objective 1 not started</string>
<string name="pumpisnottempbasalcapable">Pump is not temp basal capable</string>
<string name="novalidbasalrate">No valid basal rate read from pump</string>
</resources>

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.interfaces.contraints;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
/**
* Created by mike on 19.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class BooleanConstraintTest {
@Test
public void doTests() throws Exception {
BooleanConstraint c;
c = new BooleanConstraint(true);
Assert.assertEquals(true, c.get());
Assert.assertEquals("", c.getReasons());
c.set(false);
Assert.assertEquals(false, c.get());
Assert.assertEquals("", c.getReasons());
c.set(true, "Set true");
Assert.assertEquals(true, c.get());
Assert.assertEquals("Set true", c.getReasons());
}
}

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.interfaces.contraints;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.interfaces.constrains.DoubleConstraint;
/**
* Created by mike on 19.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class DoubleConstraintTest {
@Test
public void doTests() throws Exception {
DoubleConstraint c;
c = new DoubleConstraint(10d);
Assert.assertEquals(10d, c.getDouble());
Assert.assertEquals("", c.getReasons());
c.set(11d);
Assert.assertEquals(11d, c.getDouble());
Assert.assertEquals("", c.getReasons());
c.set(9d, "Set 9d");
Assert.assertEquals(9d, c.getDouble());
Assert.assertEquals("Set 9d", c.getReasons());
c.set(8d, "Set 8d");
Assert.assertEquals(8d, c.getDouble());
Assert.assertEquals("Set 9d\nSet 8d", c.getReasons());
}
}

View file

@ -0,0 +1,34 @@
package info.nightscout.androidaps.interfaces.contraints;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.constrains.IntegerConstraint;
/**
* Created by mike on 19.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class IntegerConstraintTest {
@Test
public void doTests() throws Exception {
IntegerConstraint c;
c = new IntegerConstraint(10);
Assert.assertEquals(10, c.getInteger());
Assert.assertEquals("", c.getReasons());
c.set(11);
Assert.assertEquals(11, c.getInteger());
Assert.assertEquals("", c.getReasons());
c.set(9, "Set 9");
Assert.assertEquals(9, c.getInteger());
Assert.assertEquals("Set 9", c.getReasons());
}
}