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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,10 +1,5 @@
package info.nightscout.androidaps.plugins.PumpInsight; 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.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.slf4j.Logger; 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.Source;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.interfaces.constrains.BooleanConstraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; 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.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
@ -1085,8 +1080,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints
// Constraints // Constraints
@Override @Override
public boolean isLoopEnabled() { public void limitRunningLoop(BooleanConstraint value){
return true;
} }
@Override @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="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_bolus_count">Bolus count</string>
<string name="combo_tbr_count">TBR 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> </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());
}
}