diff --git a/app/build.gradle b/app/build.gradle index 00c78fe077..8366358e50 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,6 +47,11 @@ def generateGitBuild = { -> return stringBuilder.toString() } +tasks.matching {it instanceof Test}.all { + testLogging.events = ["failed", "skipped"] + testLogging.exceptionFormat = "full" +} + android { compileSdkVersion 27 buildToolsVersion "${supportLibraryVersion}" @@ -57,7 +62,7 @@ android { targetSdkVersion 23 multiDexEnabled true versionCode 1500 - version "1.60-dev" + version "1.60a-dev" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() @@ -97,21 +102,6 @@ android { buildConfigField "boolean", "APS", "true" buildConfigField "boolean", "PUMPDRIVERS", "true" buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "CLOSEDLOOP", "true" - buildConfigField "boolean", "G5UPLOADER", "false" - buildConfigField "boolean", "PUMPCONTROL", "false" - } - openloop { - dimension "standard" - resValue "string", "app_name", "AndroidAPS" - versionName version - manifestPlaceholders = [ - appIcon: "@mipmap/blueowl" - ] - buildConfigField "boolean", "APS", "true" - buildConfigField "boolean", "PUMPDRIVERS", "true" - buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "CLOSEDLOOP", "false" buildConfigField "boolean", "G5UPLOADER", "false" buildConfigField "boolean", "PUMPCONTROL", "false" } @@ -125,7 +115,6 @@ android { buildConfigField "boolean", "APS", "false" buildConfigField "boolean", "PUMPDRIVERS", "true" buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "CLOSEDLOOP", "false" buildConfigField "boolean", "G5UPLOADER", "false" buildConfigField "boolean", "PUMPCONTROL", "true" } @@ -139,7 +128,6 @@ android { buildConfigField "boolean", "APS", "false" buildConfigField "boolean", "PUMPDRIVERS", "false" buildConfigField "boolean", "NSCLIENTOLNY", "true" - buildConfigField "boolean", "CLOSEDLOOP", "false" buildConfigField "boolean", "G5UPLOADER", "false" buildConfigField "boolean", "PUMPCONTROL", "false" } @@ -153,7 +141,6 @@ android { buildConfigField "boolean", "APS", "false" buildConfigField "boolean", "PUMPDRIVERS", "false" buildConfigField "boolean", "NSCLIENTOLNY", "false" - buildConfigField "boolean", "CLOSEDLOOP", "false" buildConfigField "boolean", "G5UPLOADER", "true" buildConfigField "boolean", "PUMPCONTROL", "false" } diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java index a2bf64b7ae..8e45bcecea 100644 --- a/app/src/main/java/info/nightscout/androidaps/Config.java +++ b/app/src/main/java/info/nightscout/androidaps/Config.java @@ -24,7 +24,7 @@ public class Config { public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; - public static final boolean displayDeviationSlope = true; + public static final boolean displayDeviationSlope = false; public static final boolean detailedLog = true; public static final boolean logFunctionCalls = true; diff --git a/app/src/main/java/info/nightscout/androidaps/Constants.java b/app/src/main/java/info/nightscout/androidaps/Constants.java index 0729e9d4b1..1fe9431397 100644 --- a/app/src/main/java/info/nightscout/androidaps/Constants.java +++ b/app/src/main/java/info/nightscout/androidaps/Constants.java @@ -12,10 +12,11 @@ public class Constants { public static final double defaultDIA = 3d; - public static final double basalAbsoluteOnlyForCheckLimit = 10101010d; - public static final Integer basalPercentOnlyForCheckLimit = 10101010; - public static final double bolusOnlyForCheckLimit = 10101010d; - public static final Integer carbsOnlyForCheckLimit = 10101010; + public static final Double REALLYHIGHBASALRATE = 1111111d; + public static final Integer REALLYHIGHPERCENTBASALRATE = 1111111; + public static final double REALLYHIGHBOLUS = 1111111d; + public static final Integer REALLYHIGHCARBS = 1111111; + public static final double REALLYHIGHIOB = 1111111d; public static final Integer notificationID = 556677; diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 5087fefefa..089ffa255e 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -25,12 +25,12 @@ import java.util.ArrayList; import ch.qos.logback.classic.LoggerContext; import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.data.ConstraintChecker; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.Actions.ActionsFragment; import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; @@ -42,7 +42,7 @@ import info.nightscout.androidaps.plugins.Insulin.InsulinOrefRapidActingPlugin; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefUltraRapidActingPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.receivers.AckAlarmReceiver; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; @@ -59,7 +59,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; -import info.nightscout.androidaps.plugins.PumpInsight.InsightPumpPlugin; +import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; @@ -79,7 +79,6 @@ import info.nightscout.androidaps.receivers.KeepAliveReceiver; import info.nightscout.androidaps.receivers.NSAlarmReceiver; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; -import info.nightscout.utils.SP; import io.fabric.sdk.android.Fabric; @@ -93,6 +92,7 @@ public class MainApp extends Application { private static DatabaseHelper sDatabaseHelper = null; private static ConfigBuilderPlugin sConfigBuilder = null; + private static ConstraintChecker sConstraintsChecker = null; private static ArrayList pluginsList = null; @@ -109,6 +109,7 @@ public class MainApp extends Application { super.onCreate(); sInstance = this; sResources = getResources(); + sConstraintsChecker = new ConstraintChecker(this); try { if (FabricPrivacy.fabricEnabled()) { @@ -154,7 +155,7 @@ public class MainApp extends Application { if (Config.HWPUMPS) pluginsList.add(DanaRv2Plugin.getPlugin()); if (Config.HWPUMPS) pluginsList.add(DanaRSPlugin.getPlugin()); pluginsList.add(CareportalPlugin.getPlugin()); - if (Config.HWPUMPS && engineeringMode) pluginsList.add(InsightPumpPlugin.getPlugin()); // <-- Enable Insight plugin here + if (Config.HWPUMPS && engineeringMode) pluginsList.add(InsightPlugin.getPlugin()); // <-- Enable Insight plugin here if (Config.HWPUMPS && engineeringMode) pluginsList.add(ComboPlugin.getPlugin()); // <-- Enable Combo plugin here if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin()); if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getPlugin()); @@ -184,20 +185,21 @@ public class MainApp extends Application { pluginsList.add(WearPlugin.initPlugin(this)); pluginsList.add(StatuslinePlugin.initPlugin(this)); pluginsList.add(new PersistentNotificationPlugin(this)); - pluginsList.add(NSClientInternalPlugin.getPlugin()); + pluginsList.add(NSClientPlugin.getPlugin()); - pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin()); + pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin()); MainApp.getConfigBuilder().initialize(); } NSUpload.uploadAppStart(); + if (Config.NSCLIENT) FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient")); else if (Config.G5UPLOADER) FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader")); else if (Config.PUMPCONTROL) FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl")); - else if (MainApp.getConfigBuilder().isClosedModeEnabled()) + else if (MainApp.getConstraintChecker().isClosedLoopAllowed().value()) FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop")); else FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop")); @@ -293,6 +295,10 @@ public class MainApp extends Application { return sConfigBuilder; } + public static ConstraintChecker getConstraintChecker() { + return sConstraintsChecker; + } + public static ArrayList getPluginsList() { return pluginsList; } @@ -382,6 +388,8 @@ public class MainApp extends Application { } public static boolean isEngineeringModeOrRelease() { + if (!BuildConfig.APS) + return true; return engineeringMode || !devBranch; } diff --git a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java index 0f712c787f..3d445dca7b 100644 --- a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java @@ -14,14 +14,14 @@ import android.text.TextUtils; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin; import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; import info.nightscout.androidaps.plugins.Insulin.InsulinOrefFreePeakPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; +import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; @@ -65,7 +65,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre if (key.equals("short_tabtitles")) { MainApp.bus().post(new EventRefreshGui()); } - if (key.equals("openapsama_useautosens") && SP.getBoolean("openapsama_useautosens", false)) { + if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) { OKDialog.show(this, MainApp.sResources.getString(R.string.configbuilder_sensitivity), MainApp.sResources.getString(R.string.sensitivity_warning), null); } updatePrefSummary(myPreferenceFragment.getPreference(key)); @@ -173,7 +173,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre addPreferencesFromResourceIfEnabled(InsulinOrefFreePeakPlugin.getPlugin(), PluginBase.INSULIN); - addPreferencesFromResourceIfEnabled(NSClientInternalPlugin.getPlugin(), PluginBase.GENERAL); + addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginBase.GENERAL); addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginBase.GENERAL); if (!Config.NSCLIENT && !Config.G5UPLOADER) { diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java index 07ca0fc049..a9df24798e 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java @@ -64,31 +64,31 @@ public class DataService extends IntentService { if (Config.logFunctionCalls) log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras())); - if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) { + if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) { xDripEnabled = true; nsClientEnabled = false; mm640gEnabled = false; glimpEnabled = false; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) { xDripEnabled = false; nsClientEnabled = true; mm640gEnabled = false; glimpEnabled = false; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) { xDripEnabled = false; nsClientEnabled = false; mm640gEnabled = true; glimpEnabled = false; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) { xDripEnabled = false; nsClientEnabled = false; mm640gEnabled = false; glimpEnabled = true; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) { xDripEnabled = false; nsClientEnabled = false; mm640gEnabled = false; @@ -192,7 +192,7 @@ public class DataService extends IntentService { bgReading.date = bundle.getLong(Intents.EXTRA_TIMESTAMP); bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW); - MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP", xDripEnabled); + MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP"); } private void handleNewDataFromGlimp(Intent intent) { @@ -206,7 +206,7 @@ public class DataService extends IntentService { bgReading.date = bundle.getLong("myTimestamp"); bgReading.raw = 0; - MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP", glimpEnabled); + MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP"); } private void handleNewDataFromDexcomG5(Intent intent) { @@ -229,7 +229,7 @@ public class DataService extends IntentService { bgReading.direction = json.getString("m_trend"); bgReading.date = json.getLong("m_time") * 1000L; bgReading.raw = 0; - boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "DexcomG5", dexcomG5Enabled); + boolean isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "DexcomG5"); if (isNew && SP.getBoolean(R.string.key_dexcomg5_nsupload, false)) { NSUpload.uploadBg(bgReading); } @@ -268,7 +268,7 @@ public class DataService extends IntentService { bgReading.date = json_object.getLong("date"); bgReading.raw = json_object.getDouble("sgv"); - MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g", mm640gEnabled); + MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g"); break; default: log.debug("Unknown entries type: " + type); @@ -425,7 +425,7 @@ public class DataService extends IntentService { JSONObject sgvJson = new JSONObject(sgvstring); NSSgv nsSgv = new NSSgv(sgvJson); BgReading bgReading = new BgReading(nsSgv); - MainApp.getDbHelper().createIfNotExists(bgReading, "NS", nsClientEnabled); + MainApp.getDbHelper().createIfNotExists(bgReading, "NS"); } if (bundles.containsKey("sgvs")) { @@ -435,7 +435,7 @@ public class DataService extends IntentService { JSONObject sgvJson = jsonArray.getJSONObject(i); NSSgv nsSgv = new NSSgv(sgvJson); BgReading bgReading = new BgReading(nsSgv); - MainApp.getDbHelper().createIfNotExists(bgReading, "NS", nsClientEnabled); + MainApp.getDbHelper().createIfNotExists(bgReading, "NS"); } } } catch (Exception e) { diff --git a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java new file mode 100644 index 0000000000..6c13075a3c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java @@ -0,0 +1,197 @@ +package info.nightscout.androidaps.data; + +import java.util.ArrayList; + +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +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.plugins.ConfigBuilder.ConfigBuilderPlugin; + +/** + * Created by mike on 19.03.2018. + */ + +public class ConstraintChecker implements ConstraintsInterface { + + private MainApp mainApp; + + public ConstraintChecker(MainApp mainApp) { + this.mainApp = mainApp; + } + + + public Constraint isLoopInvokationAllowed() { + return isLoopInvokationAllowed(new Constraint<>(true)); + } + + public Constraint isClosedLoopAllowed() { + return isClosedLoopAllowed(new Constraint<>(true)); + } + + public Constraint isAutosensModeEnabled() { + return isAutosensModeEnabled(new Constraint<>(true)); + } + + public Constraint isAMAModeEnabled() { + return isAMAModeEnabled(new Constraint<>(true)); + } + + public Constraint isSMBModeEnabled() { + return isSMBModeEnabled(new Constraint<>(true)); + } + + public Constraint isAdvancedFilteringEnabled() { + return isAdvancedFilteringEnabled(new Constraint<>(true)); + } + + public Constraint getMaxBasalAllowed(Profile profile) { + return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile); + } + + public Constraint getMaxBasalPercentAllowed(Profile profile) { + return applyBasalPercentConstraints(new Constraint<>(Constants.REALLYHIGHPERCENTBASALRATE), profile); + } + + public Constraint getMaxBolusAllowed() { + return applyBolusConstraints(new Constraint<>(Constants.REALLYHIGHBOLUS)); + } + + public Constraint getMaxCarbsAllowed() { + return applyCarbsConstraints(new Constraint<>(Constants.REALLYHIGHCARBS)); + } + + public Constraint getMaxIOBAllowed() { + return applyMaxIOBConstraints(new Constraint<>(Constants.REALLYHIGHIOB)); + } + + @Override + public Constraint isLoopInvokationAllowed(Constraint value) { + + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.isLoopInvokationAllowed(value); + } + return value; + } + + @Override + public Constraint isClosedLoopAllowed(Constraint value) { + + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.isClosedLoopAllowed(value); + } + return value; + } + + @Override + public Constraint isAutosensModeEnabled(Constraint value) { + + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.isAutosensModeEnabled(value); + } + return value; + } + + @Override + public Constraint isAMAModeEnabled(Constraint value) { + + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constrain = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constrain.isAMAModeEnabled(value); + } + return value; + } + + @Override + public Constraint isSMBModeEnabled(Constraint value) { + + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.isSMBModeEnabled(value); + } + return value; + } + + @Override + public Constraint isAdvancedFilteringEnabled(Constraint value) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.isAdvancedFilteringEnabled(value); + } + return value; + } + + @Override + public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.applyBasalConstraints(absoluteRate, profile); + } + return absoluteRate; + } + + @Override + public Constraint applyBasalPercentConstraints(Constraint percentRate, Profile profile) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constrain = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constrain.applyBasalPercentConstraints(percentRate, profile); + } + return percentRate; + } + + @Override + public Constraint applyBolusConstraints(Constraint insulin) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constrain = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constrain.applyBolusConstraints(insulin); + } + return insulin; + } + + @Override + public Constraint applyCarbsConstraints(Constraint carbs) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constrain = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constrain.applyCarbsConstraints(carbs); + } + return carbs; + } + + @Override + public Constraint applyMaxIOBConstraints(Constraint maxIob) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constrain = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constrain.applyMaxIOBConstraints(maxIob); + } + return maxIob; + } + + +} diff --git a/app/src/main/java/info/nightscout/androidaps/data/Intervals.java b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java index 108b4060e0..7213290aa5 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Intervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java @@ -16,7 +16,15 @@ import info.nightscout.androidaps.interfaces.Interval; public abstract class Intervals { - LongSparseArray rawData = new LongSparseArray(); // oldest at index 0 + LongSparseArray rawData; // oldest at index 0 + + public Intervals() { + rawData = new LongSparseArray(); + } + + public Intervals(LongSparseArray data) { + rawData = data; + } public synchronized Intervals reset() { rawData = new LongSparseArray(); @@ -27,8 +35,7 @@ public abstract class Intervals { /** * The List must be sorted by `T.start()` in ascending order - * - * */ + */ public synchronized void add(List list) { for (T interval : list) { rawData.put(interval.start(), interval); @@ -37,7 +44,6 @@ public abstract class Intervals { } - public synchronized List getList() { List list = new ArrayList<>(); for (int i = 0; i < rawData.size(); i++) @@ -47,7 +53,7 @@ public abstract class Intervals { public synchronized List getReversedList() { List list = new ArrayList<>(); - for (int i = rawData.size() -1; i>=0; i--) + for (int i = rawData.size() - 1; i >= 0; i--) list.add(rawData.valueAt(i)); return list; } @@ -86,5 +92,4 @@ public abstract class Intervals { } - } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java index 385eeb9594..d54aa252c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java @@ -2,7 +2,9 @@ package info.nightscout.androidaps.data; import android.support.annotation.Nullable; +import android.support.v4.util.LongSparseArray; +import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.interfaces.Interval; /** @@ -11,6 +13,18 @@ import info.nightscout.androidaps.interfaces.Interval; public class NonOverlappingIntervals extends Intervals { + public NonOverlappingIntervals() { + super(); + } + + public NonOverlappingIntervals(LongSparseArray data) { + super(data); + } + + public NonOverlappingIntervals (Intervals other) { + rawData = other.rawData.clone(); + } + protected synchronized void merge() { for (int index = 0; index < rawData.size() - 1; index++) { Interval i = rawData.valueAt(index); @@ -27,4 +41,5 @@ public class NonOverlappingIntervals extends Intervals { if (index >= 0) return rawData.valueAt(index); return null; } + } diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java index 8ea89e2a5b..caf15b5b90 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java @@ -22,7 +22,15 @@ import info.nightscout.utils.DateUtil; public class ProfileIntervals { private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class); - private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 + private LongSparseArray rawData; // oldest at index 0 + + public ProfileIntervals () { + rawData = new LongSparseArray<>(); + } + + public ProfileIntervals (ProfileIntervals other) { + rawData = other.rawData.clone(); + } public synchronized ProfileIntervals reset() { rawData = new LongSparseArray<>(); @@ -58,7 +66,7 @@ public class ProfileIntervals { if (index >= 0) return rawData.valueAt(index); // if we request data older than first record, use oldest instead if (rawData.size() > 0) { - log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); + //log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); return rawData.valueAt(0); } return null; @@ -117,4 +125,9 @@ public class ProfileIntervals { public synchronized T getReversed(int index) { return rawData.valueAt(size() - 1 - index); } + + @Override + public String toString() { + return rawData.toString(); + } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java b/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java index 9aa09244aa..264a153c5e 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java +++ b/app/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java @@ -97,19 +97,23 @@ public class PumpEnactResult { if (bolusDelivered > 0) { ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment; - ret += "\n" + MainApp.sResources.getString(R.string.smb_shortname) + ": " + bolusDelivered + "U"; + ret += "\n" + MainApp.sResources.getString(R.string.smb_shortname) + + ": " + bolusDelivered + " " + MainApp.gs(R.string.insulin_unit_shortname); } else if (isTempCancel) { ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; - ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment + "\n" + - MainApp.sResources.getString(R.string.canceltemp); + if (!comment.isEmpty()) + ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment; + ret += MainApp.sResources.getString(R.string.canceltemp); } else if (isPercent) { ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; - ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment; + if (!comment.isEmpty()) + ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment; ret += "\n" + MainApp.sResources.getString(R.string.duration) + ": " + duration + " min"; ret += "\n" + MainApp.sResources.getString(R.string.percent) + ": " + percent + "%"; } else { ret += "\n" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; - ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment; + if (!comment.isEmpty()) + ret += "\n" + MainApp.sResources.getString(R.string.comment) + ": " + comment; ret += "\n" + MainApp.sResources.getString(R.string.duration) + ": " + duration + " min"; ret += "\n" + MainApp.sResources.getString(R.string.absolute) + ": " + absolute + " U/h"; } @@ -126,26 +130,26 @@ public class PumpEnactResult { } else if (enacted) { if (bolusDelivered > 0) { ret += "
" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; - ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; - ret += "
" + MainApp.sResources.getString(R.string.smb_shortname) + ": " + bolusDelivered + "U"; + if (!comment.isEmpty()) + ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; + ret += "
" + MainApp.sResources.getString(R.string.smb_shortname) + ": " + bolusDelivered + " " + MainApp.gs(R.string.insulin_unit_shortname); } else if (isTempCancel) { ret += "
" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment + "
" + MainApp.sResources.getString(R.string.canceltemp); } else if (isPercent && percent != -1) { ret += "
" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; - ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; + if (!comment.isEmpty()) + ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; ret += "
" + MainApp.sResources.getString(R.string.duration) + ": " + duration + " min"; ret += "
" + MainApp.sResources.getString(R.string.percent) + ": " + percent + "%"; } else if (absolute != -1) { ret += "
" + MainApp.sResources.getString(R.string.enacted) + ": " + enacted; - ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; + if (!comment.isEmpty()) + ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; ret += "
" + MainApp.sResources.getString(R.string.duration) + ": " + duration + " min"; ret += "
" + MainApp.sResources.getString(R.string.absolute) + ": " + DecimalFormatter.to2Decimal(absolute) + " U/h"; } - if (bolusDelivered > 0) { - ret += "
" + MainApp.sResources.getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusDelivered) + " U"; - } } else { ret += "
" + MainApp.sResources.getString(R.string.comment) + ": " + comment; } diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index dc0955ba83..b65fc2d542 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -8,6 +8,7 @@ import android.support.annotation.Nullable; import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; import com.j256.ormlite.dao.CloseableIterator; import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.DaoManager; import com.j256.ormlite.stmt.PreparedQuery; import com.j256.ormlite.stmt.QueryBuilder; import com.j256.ormlite.stmt.Where; @@ -246,7 +247,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { log.error("Unhandled exception", e); } VirtualPumpPlugin.setFakingStatus(true); - scheduleBgChange(null, false, false); // trigger refresh + scheduleBgChange(null); // trigger refresh scheduleTemporaryBasalChange(); scheduleTreatmentChange(null); scheduleExtendedBolusChange(); @@ -384,14 +385,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } // ------------------- BgReading handling ----------------------- - public boolean createIfNotExists(BgReading bgReading, String from, boolean isFromActiveBgSource) { + public boolean createIfNotExists(BgReading bgReading, String from) { try { bgReading.date = roundDateToSec(bgReading.date); BgReading old = getDaoBgReadings().queryForId(bgReading.date); if (old == null) { getDaoBgReadings().create(bgReading); log.debug("BG: New record from: " + from + " " + bgReading.toString()); - scheduleBgChange(bgReading, true, isFromActiveBgSource); + scheduleBgChange(bgReading); return true; } if (!old.isEqual(bgReading)) { @@ -399,7 +400,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { old.copyFrom(bgReading); getDaoBgReadings().update(old); log.debug("BG: Updating record from: " + from + " New data: " + old.toString()); - scheduleBgChange(bgReading, false, isFromActiveBgSource); + scheduleBgChange(bgReading); return false; } } catch (SQLException e) { @@ -417,11 +418,11 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } } - private static void scheduleBgChange(@Nullable final BgReading bgReading, boolean isNew, boolean isFromActiveBgSource) { + private static void scheduleBgChange(@Nullable final BgReading bgReading) { class PostRunnable implements Runnable { public void run() { log.debug("Firing EventNewBg"); - MainApp.bus().post(new EventNewBG(bgReading, isNew, isFromActiveBgSource)); + MainApp.bus().post(new EventNewBG(bgReading)); scheduledBgPost = null; } } diff --git a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java index 4b4bfcb08d..31df191387 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java +++ b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java @@ -128,7 +128,7 @@ public class Treatment implements DataPointWithLabelInterface { @Override public String getLabel() { String label = ""; - if (insulin > 0) label += DecimalFormatter.to2Decimal(insulin) + "U"; + if (insulin > 0) label += DecimalFormatter.toPumpSupportedBolus(insulin) + "U"; if (carbs > 0) label += "~" + DecimalFormatter.to0Decimal(carbs) + "g"; return label; @@ -149,7 +149,7 @@ public class Treatment implements DataPointWithLabelInterface { @Override public float getSize() { - return 10; + return 2; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventNewBG.java b/app/src/main/java/info/nightscout/androidaps/events/EventNewBG.java index e65c02a58c..dc4d434e0a 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventNewBG.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventNewBG.java @@ -10,17 +10,8 @@ import info.nightscout.androidaps.db.BgReading; public class EventNewBG extends EventLoop { @Nullable public final BgReading bgReading; - public final boolean isNew; - public final boolean isFromActiveBgSource; - /** Whether the BgReading is current (enough to use for treatment decisions). */ - public boolean isCurrent() { - return bgReading != null && bgReading.date + 9 * 60 * 1000 > System.currentTimeMillis(); - } - - public EventNewBG(@Nullable BgReading bgReading, boolean isNew, boolean isFromActiveBgSource) { + public EventNewBG(BgReading bgReading) { this.bgReading = bgReading; - this.isNew = isNew; - this.isFromActiveBgSource = isFromActiveBgSource; } } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java b/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java new file mode 100644 index 0000000000..58e6045bd1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/Constraint.java @@ -0,0 +1,117 @@ +package info.nightscout.androidaps.interfaces; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by mike on 19.03.2018. + */ + +public class Constraint { + private static Logger log = LoggerFactory.getLogger(Constraint.class); + + T value; + T originalValue; + + List reasons = new ArrayList<>(); + List mostLimiting = new ArrayList<>(); + + public Constraint(T value) { + this.value = value; + this.originalValue = value; + } + + public T value() { + return value; + } + + public T originalValue() { + return originalValue; + } + + public Constraint set(T value) { + this.value = value; + this.originalValue = value; + return this; + } + + public Constraint set(T value, String reason, Object from) { + this.value = value; + addReason(reason, from); + addMostLimingReason(reason, from); + return this; + } + + public Constraint setIfSmaller(T value, String reason, Object from) { + if (value.compareTo(this.value) < 0) { + this.value = value; + mostLimiting.clear(); + addMostLimingReason(reason, from); + } + if (value.compareTo(this.originalValue) < 0) { + addReason(reason, from); + } + return this; + } + + public Constraint setIfGreater(T value, String reason, Object from) { + if (value.compareTo(this.value) > 0) { + this.value = value; + mostLimiting.clear(); + addMostLimingReason(reason, from); + } + if (value.compareTo(this.originalValue) > 0) { + addReason(reason, from); + } + return this; + } + + public Constraint addReason(String reason, Object from) { + reasons.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + reason); + return this; + } + + public Constraint addMostLimingReason(String reason, Object from) { + mostLimiting.add(from.getClass().getSimpleName().replace("Plugin", "") + ": " + 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); + } + log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString()); + return sb.toString(); + } + + public List getReasonList() { + return reasons; + } + + public String getMostLimitedReasons() { + StringBuilder sb = new StringBuilder(); + int count = 0; + for (String r : mostLimiting) { + if (count++ != 0) sb.append("\n"); + sb.append(r); + } + log.debug("Limiting origial value: " + originalValue + " to " + value + ". Reason: " + sb.toString()); + return sb.toString(); + } + + public List getMostLimitedReasonList() { + return mostLimiting; + } + + public void copyReasons(Constraint another) { + for (String s: another.getReasonList()) { + reasons.add(s); + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java index aac7918bdc..a1daa08a56 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java @@ -1,30 +1,54 @@ package info.nightscout.androidaps.interfaces; -import info.nightscout.androidaps.plugins.Loop.APSResult; +import info.nightscout.androidaps.data.Profile; /** * Created by mike on 15.06.2016. */ public interface ConstraintsInterface { - boolean isLoopEnabled(); + default Constraint isLoopInvokationAllowed(Constraint value) { + return value; + } - boolean isClosedModeEnabled(); + default Constraint isClosedLoopAllowed(Constraint value) { + return value; + } - boolean isAutosensModeEnabled(); + default Constraint isAutosensModeEnabled(Constraint value) { + return value; + } - boolean isAMAModeEnabled(); + default Constraint isAMAModeEnabled(Constraint value) { + return value; + } - boolean isSMBModeEnabled(); + default Constraint isSMBModeEnabled(Constraint value) { + return value; + } - Double applyBasalConstraints(Double absoluteRate); + default Constraint isAdvancedFilteringEnabled(Constraint value) { + return value; + } - Integer applyBasalConstraints(Integer percentRate); + default Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { + return absoluteRate; + } - Double applyBolusConstraints(Double insulin); + default Constraint applyBasalPercentConstraints(Constraint percentRate, Profile profile) { + return percentRate; + } - Integer applyCarbsConstraints(Integer carbs); + default Constraint applyBolusConstraints(Constraint insulin) { + return insulin; + } - Double applyMaxIOBConstraints(Double maxIob); + default Constraint applyCarbsConstraints(Constraint carbs) { + return carbs; + } + + default Constraint applyMaxIOBConstraints(Constraint maxIob) { + return maxIob; + }; } diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java index 08db6210d4..75101b2413 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PluginBase.java @@ -28,7 +28,7 @@ public interface PluginBase { boolean canBeHidden(int type); boolean hasFragment(); boolean showInList(int type); - void setFragmentEnabled(int type, boolean fragmentEnabled); + void setPluginEnabled(int type, boolean fragmentEnabled); void setFragmentVisible(int type, boolean fragmentVisible); int getPreferencesId(); } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java index d8d56ed599..65911f82c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java @@ -35,8 +35,8 @@ public interface PumpInterface { PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo); void stopBolusDelivering(); - PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew); - PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, boolean enforceNew); + PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, 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 diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java index ce0148d963..fa79b9e100 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java @@ -126,7 +126,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL activity.runOnUiThread(new Runnable() { @Override public void run() { - if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) { + if (MainApp.getConfigBuilder().getProfile() == null) { tempTarget.setVisibility(View.GONE); profileSwitch.setVisibility(View.GONE); extendedBolus.setVisibility(View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java index 3c71626e64..3de3acbf18 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsPlugin.java @@ -65,7 +65,7 @@ public class ActionsPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java index 8297e28412..b3b15bf7fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java @@ -1,11 +1,11 @@ package info.nightscout.androidaps.plugins.Actions.dialogs; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; +import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -13,24 +13,31 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.Button; +import android.widget.CheckBox; import com.crashlytics.android.answers.CustomEvent; +import com.google.common.base.Joiner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.text.DecimalFormat; - import info.nightscout.androidaps.Constants; +import java.text.DecimalFormat; +import java.util.LinkedList; +import java.util.List; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -38,13 +45,13 @@ import info.nightscout.utils.SafeParse; public class FillDialog extends DialogFragment implements OnClickListener { private static Logger log = LoggerFactory.getLogger(FillDialog.class); - Button deliverButton; - double amount1 = 0d; double amount2 = 0d; double amount3 = 0d; NumberPicker editInsulin; + CheckBox pumpSiteChangeCheckbox; + CheckBox insulinCartridgeChangeCheckbox; public FillDialog() { } @@ -54,22 +61,24 @@ public class FillDialog extends DialogFragment implements OnClickListener { Bundle savedInstanceState) { View view = inflater.inflate(R.layout.actions_fill_dialog, null, false); - deliverButton = (Button) view.findViewById(R.id.treatments_newtreatment_deliverbutton); + view.findViewById(R.id.ok).setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); - deliverButton.setOnClickListener(this); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + pumpSiteChangeCheckbox = view.findViewById(R.id.catheter_change); + insulinCartridgeChangeCheckbox = view.findViewById(R.id.cartridge_change); + + Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; - editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); - editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false); + editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount); + editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false); //setup preset buttons Button button1 = (Button) view.findViewById(R.id.fill_preset_button1); Button button2 = (Button) view.findViewById(R.id.fill_preset_button2); Button button3 = (Button) view.findViewById(R.id.fill_preset_button3); - View divider = view.findViewById(R.id.fill_preset_divider); amount1 = SP.getDouble("fill_button1", 0.3); amount2 = SP.getDouble("fill_button2", 0d); @@ -77,103 +86,109 @@ public class FillDialog extends DialogFragment implements OnClickListener { if (amount1 > 0) { button1.setVisibility(View.VISIBLE); - button1.setText(DecimalFormatter.to2Decimal(amount1) + "U"); + button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U"); button1.setOnClickListener(this); } else { button1.setVisibility(View.GONE); } if (amount2 > 0) { button2.setVisibility(View.VISIBLE); - button2.setText(DecimalFormatter.to2Decimal(amount2) + "U"); + button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U"); button2.setOnClickListener(this); } else { button2.setVisibility(View.GONE); } if (amount3 > 0) { button3.setVisibility(View.VISIBLE); - button3.setText(DecimalFormatter.to2Decimal(amount3) + "U"); + button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U"); button3.setOnClickListener(this); } else { button3.setVisibility(View.GONE); } - if (button1.getVisibility() == View.GONE && button2.getVisibility() == View.GONE && button3.getVisibility() == View.GONE) { - divider.setVisibility(View.GONE); - } - setCancelable(true); getDialog().setCanceledOnTouchOutside(false); return view; } - @Override - public void onResume() { - super.onResume(); - if (getDialog() != null) - getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - } - @Override public void onClick(View view) { switch (view.getId()) { - case R.id.treatments_newtreatment_deliverbutton: - Double insulin = SafeParse.stringToDouble(editInsulin.getText().toString()); - confirmAndDeliver(insulin); + case R.id.ok: + confirmAndDeliver(); + break; + case R.id.cancel: + dismiss(); break; case R.id.fill_preset_button1: - confirmAndDeliver(amount1); + editInsulin.setValue(amount1); break; case R.id.fill_preset_button2: - confirmAndDeliver(amount2); + editInsulin.setValue(amount2); break; case R.id.fill_preset_button3: - confirmAndDeliver(amount3); + editInsulin.setValue(amount3); break; } } - private void confirmAndDeliver(Double insulin) { + private void confirmAndDeliver() { try { + Double insulin = SafeParse.stringToDouble(editInsulin.getText()); - String confirmMessage = getString(R.string.fillwarning) + "\n"; + List confirmMessage = new LinkedList<>(); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin); - confirmMessage += getString(R.string.bolus) + ": " + insulinAfterConstraints + "U"; - if (insulinAfterConstraints - insulin != 0) - confirmMessage += "\n" + getString(R.string.constraintapllied); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + if (insulinAfterConstraints > 0) { + confirmMessage.add(MainApp.gs(R.string.fillwarning)); + confirmMessage.add(""); + confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""); + if (!insulinAfterConstraints.equals(insulin)) + confirmMessage.add("" + MainApp.gs(R.string.bolusconstraintapplied) + ""); + } + + if (pumpSiteChangeCheckbox.isChecked()) + confirmMessage.add("" + "" + getString(R.string.record_pump_site_change) + ""); + + if (insulinCartridgeChangeCheckbox.isChecked()) + confirmMessage.add("" + "" + getString(R.string.record_insulin_cartridge_change) + ""); final Double finalInsulinAfterConstraints = insulinAfterConstraints; final Context context = getContext(); AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(this.getContext().getString(R.string.confirmation)); - builder.setMessage(confirmMessage); - builder.setPositiveButton(getString(R.string.primefill), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - if (finalInsulinAfterConstraints > 0) { - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.insulin = finalInsulinAfterConstraints; - detailedBolusInfo.context = context; - detailedBolusInfo.source = Source.USER; - detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { - @Override - public void run() { - if (!result.success) { - Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); - i.putExtra("soundid", R.raw.boluserror); - i.putExtra("status", result.comment); - i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror)); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - MainApp.instance().startActivity(i); - } + if (confirmMessage.isEmpty()) + confirmMessage.add(MainApp.gs(R.string.no_action_selected)); + + builder.setTitle(MainApp.gs(R.string.confirmation)); + builder.setMessage(Html.fromHtml(Joiner.on("
").join(confirmMessage))); + builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> { + if (finalInsulinAfterConstraints > 0) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.insulin = finalInsulinAfterConstraints; + detailedBolusInfo.context = context; + detailedBolusInfo.source = Source.USER; + detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) + ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + if (!result.success) { + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.boluserror); + i.putExtra("status", result.comment); + i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); } - }); - FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); - } + } + }); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); } + long now = System.currentTimeMillis(); + if (pumpSiteChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now); + if (insulinCartridgeChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now + 1000); }); builder.setNegativeButton(getString(R.string.cancel), null); builder.show(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java index e2bcbe2acd..04dd783b04 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java @@ -17,9 +17,9 @@ import org.slf4j.LoggerFactory; import java.text.DecimalFormat; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; @@ -43,7 +43,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli View view = inflater.inflate(R.layout.overview_newextendedbolus_dialog, container, false); - Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); editInsulin = (NumberPicker) view.findViewById(R.id.overview_newextendedbolus_insulin); editInsulin.setParams(0d, 0d, maxInsulin, 0.1d, new DecimalFormat("0.00"), false); @@ -70,7 +70,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli String confirmMessage = getString(R.string.setextendedbolusquestion); - Double insulinAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(insulin); + Double insulinAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); confirmMessage += " " + insulinAfterConstraint + " U "; confirmMessage += getString(R.string.duration) + " " + durationInMinutes + "min ?"; if (insulinAfterConstraint - insulin != 0d) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java index 8e5c1737c9..fb00879ae4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java @@ -22,6 +22,7 @@ import java.text.DecimalFormat; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; @@ -117,17 +118,21 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi final boolean setAsPercent = percentRadio.isChecked(); int durationInMinutes = SafeParse.stringToInt(duration.getText()); + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) + return; + String confirmMessage = getString(R.string.setbasalquestion); if (setAsPercent) { int basalPercentInput = SafeParse.stringToInt(basalPercent.getText()); - percent = MainApp.getConfigBuilder().applyBasalConstraints(basalPercentInput); + percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(basalPercentInput), profile).value(); confirmMessage += "\n" + percent + "% "; confirmMessage += "\n" + getString(R.string.duration) + " " + durationInMinutes + "min ?"; if (percent != basalPercentInput) confirmMessage += "\n" + getString(R.string.constraintapllied); } else { Double basalAbsoluteInput = SafeParse.stringToDouble(basalAbsolute.getText()); - absolute = MainApp.getConfigBuilder().applyBasalConstraints(basalAbsoluteInput); + absolute = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(basalAbsoluteInput), profile).value(); confirmMessage += "\n" + absolute + " U/h "; confirmMessage += "\n" + getString(R.string.duration) + " " + durationInMinutes + "min ?"; if (absolute - basalAbsoluteInput != 0d) @@ -157,9 +162,9 @@ 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, callback); + ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, profile, callback); } FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal")); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java index a72fc200ea..1cfd5822ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalPlugin.java @@ -71,7 +71,7 @@ public class CareportalPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java index 99fc44341b..b383dd1519 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java @@ -51,15 +51,16 @@ import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventNewBasalProfile; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.HardLimits; import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; -import info.nightscout.utils.OKDialog; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.Translator; @@ -108,6 +109,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick Date eventTime; + private static Integer seconds = null; + public void setOptions(OptionsToShow options, int event) { this.options = options; this.event = MainApp.sResources.getString(event); @@ -115,6 +118,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public NewNSTreatmentDialog() { super(); + + if (seconds == null) { + seconds = new Double(Math.random() * 59).intValue(); + } } @Override @@ -272,11 +279,11 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } }); - Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); + Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); editCarbs = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_carbsinput); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false); - Double maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); editInsulin = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_insulininput); editInsulin.setParams(0d, 0d, maxInsulin, 0.05d, new DecimalFormat("0.00"), false); @@ -303,7 +310,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } }; - Integer maxPercent = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalPercentOnlyForCheckLimit); + Integer maxPercent = 200; + if (profile != null) + maxPercent = MainApp.getConstraintChecker().getMaxBasalPercentAllowed(profile).value(); editPercent = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_percentinput); editPercent.setParams(0d, 0d, (double) maxPercent, 5d, new DecimalFormat("0"), true, percentTextWatcher); @@ -325,7 +334,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } }; - Double maxAbsolute = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalAbsoluteOnlyForCheckLimit); + Double maxAbsolute = HardLimits.maxBasal(); + if (profile != null) + maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput); editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher); @@ -419,8 +430,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000 List data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true); if ((data.size() > 0) && - (data.get(0).date > millis - 7 * 60 * 1000L) && - (data.get(0).date < millis + 7 * 60 * 1000L)) { + (data.get(0).date > millis - 7 * 60 * 1000L) && + (data.get(0).date < millis + 7 * 60 * 1000L)) { editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL)); } } @@ -438,7 +449,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) { eventTime.setHours(hourOfDay); eventTime.setMinutes(minute); - eventTime.setSeconds(second); + eventTime.setSeconds(this.seconds++); // randomize seconds to prevent creating record of the same time, if user choose time manually timeButton.setText(DateUtil.timeString(eventTime)); updateBGforDateTime(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java index 8d4c74d607..da3dba05a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java @@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.ConfigBuilder; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.Fragment; +import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -17,11 +17,13 @@ import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; - import com.crashlytics.android.answers.CustomEvent; import java.util.ArrayList; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.PreferencesActivity; import info.nightscout.androidaps.R; @@ -35,6 +37,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; @@ -43,33 +46,46 @@ import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.PasswordProtection; -public class ConfigBuilderFragment extends Fragment { - - static ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin(); - - static public ConfigBuilderPlugin getPlugin() { - return configBuilderPlugin; - } +public class ConfigBuilderFragment extends SubscriberFragment { + @BindView(R.id.configbuilder_insulinlistview) ListView insulinListView; + @BindView(R.id.configbuilder_sensitivitylistview) ListView sensitivityListView; + @BindView(R.id.configbuilder_bgsourcelistview) ListView bgsourceListView; + @BindView(R.id.configbuilder_bgsourcelabel) TextView bgsourceLabel; + @BindView(R.id.configbuilder_pumplistview) ListView pumpListView; + @BindView(R.id.configbuilder_pumplabel) TextView pumpLabel; + @BindView(R.id.configbuilder_looplistview) ListView loopListView; + @BindView(R.id.configbuilder_looplabel) TextView loopLabel; + @BindView(R.id.configbuilder_treatmentslistview) ListView treatmentsListView; + @BindView(R.id.configbuilder_treatmentslabel) TextView treatmentsLabel; + @BindView(R.id.configbuilder_profilelistview) ListView profileListView; + @BindView(R.id.configbuilder_profilelabel) TextView profileLabel; + @BindView(R.id.configbuilder_apslistview) ListView apsListView; + @BindView(R.id.configbuilder_apslabel) TextView apsLabel; + @BindView(R.id.configbuilder_constraintslistview) ListView constraintsListView; + @BindView(R.id.configbuilder_constraintslabel) TextView constraintsLabel; + @BindView(R.id.configbuilder_generallistview) ListView generalListView; + @BindView(R.id.configbuilder_mainlayout) LinearLayout mainLayout; + @BindView(R.id.configbuilder_unlock) Button unlock; PluginCustomAdapter insulinDataAdapter = null; @@ -84,51 +100,17 @@ public class ConfigBuilderFragment extends Fragment { PluginCustomAdapter generalDataAdapter = null; @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { try { View view = inflater.inflate(R.layout.configbuilder_fragment, container, false); - insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview); - sensitivityListView = (ListView) view.findViewById(R.id.configbuilder_sensitivitylistview); - bgsourceListView = (ListView) view.findViewById(R.id.configbuilder_bgsourcelistview); - bgsourceLabel = (TextView) view.findViewById(R.id.configbuilder_bgsourcelabel); - pumpListView = (ListView) view.findViewById(R.id.configbuilder_pumplistview); - pumpLabel = (TextView) view.findViewById(R.id.configbuilder_pumplabel); - loopListView = (ListView) view.findViewById(R.id.configbuilder_looplistview); - loopLabel = (TextView) view.findViewById(R.id.configbuilder_looplabel); - treatmentsListView = (ListView) view.findViewById(R.id.configbuilder_treatmentslistview); - treatmentsLabel = (TextView) view.findViewById(R.id.configbuilder_treatmentslabel); - profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview); - profileLabel = (TextView) view.findViewById(R.id.configbuilder_profilelabel); - apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview); - apsLabel = (TextView) view.findViewById(R.id.configbuilder_apslabel); - constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview); - constraintsLabel = (TextView) view.findViewById(R.id.configbuilder_constraintslabel); - generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview); + unbinder = ButterKnife.bind(this, view); - mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout); - unlock = (Button) view.findViewById(R.id.configbuilder_unlock); - - setViews(); - - if (PasswordProtection.isLocked("settings_password")) { + if (PasswordProtection.isLocked("settings_password")) mainLayout.setVisibility(View.GONE); - unlock.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - mainLayout.setVisibility(View.VISIBLE); - unlock.setVisibility(View.GONE); - } - }, null); - } - }); - } else { + else unlock.setVisibility(View.GONE); - } return view; } catch (Exception e) { FabricPrivacy.logException(e); @@ -137,7 +119,18 @@ public class ConfigBuilderFragment extends Fragment { return null; } - void setViews() { + @OnClick(R.id.configbuilder_unlock) + public void onClickUnlock() { + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + mainLayout.setVisibility(View.VISIBLE); + unlock.setVisibility(View.GONE); + }, null); + } + + + @Override + protected void updateGUI() { + insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginBase.INSULIN), PluginBase.INSULIN); insulinListView.setAdapter(insulinDataAdapter); setListViewHeightBasedOnChildren(insulinListView); @@ -182,7 +175,6 @@ public class ConfigBuilderFragment extends Fragment { generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.GENERAL), PluginBase.GENERAL); generalListView.setAdapter(generalDataAdapter); setListViewHeightBasedOnChildren(generalListView); - } /* @@ -194,8 +186,8 @@ public class ConfigBuilderFragment extends Fragment { private ArrayList pluginList; final private int type; - public PluginCustomAdapter(Context context, int textViewResourceId, - ArrayList pluginList, int type) { + PluginCustomAdapter(Context context, int textViewResourceId, + ArrayList pluginList, int type) { super(context, textViewResourceId, pluginList); this.pluginList = new ArrayList<>(); this.pluginList.addAll(pluginList); @@ -209,10 +201,11 @@ public class ConfigBuilderFragment extends Fragment { ImageView settings; } + @NonNull @Override - public View getView(int position, View view, ViewGroup parent) { + public View getView(int position, View view, @NonNull ViewGroup parent) { - PluginViewHolder holder = null; + PluginViewHolder holder; PluginBase plugin = pluginList.get(position); if (view == null) { @@ -231,60 +224,45 @@ public class ConfigBuilderFragment extends Fragment { view.setTag(holder); - holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - CheckBox cb = (CheckBox) v; - PluginBase plugin = (PluginBase) cb.getTag(); - plugin.setFragmentEnabled(type, cb.isChecked()); - plugin.setFragmentVisible(type, cb.isChecked()); - onEnabledCategoryChanged(plugin, type); - configBuilderPlugin.storeSettings(); - MainApp.bus().post(new EventRefreshGui()); - MainApp.bus().post(new EventConfigBuilderChange()); - getPlugin().logPluginStatus(); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); - } + holder.checkboxEnabled.setOnClickListener(v -> { + CheckBox cb = (CheckBox) v; + PluginBase plugin1 = (PluginBase) cb.getTag(); + plugin1.setPluginEnabled(type, cb.isChecked()); + plugin1.setFragmentVisible(type, cb.isChecked()); + onEnabledCategoryChanged(plugin1, type); + ConfigBuilderPlugin.getPlugin().storeSettings(); + MainApp.bus().post(new EventRefreshGui()); + MainApp.bus().post(new EventConfigBuilderChange()); + ConfigBuilderPlugin.getPlugin().logPluginStatus(); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); }); - holder.checkboxVisible.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - CheckBox cb = (CheckBox) v; - PluginBase plugin = (PluginBase) cb.getTag(); - plugin.setFragmentVisible(type, cb.isChecked()); - configBuilderPlugin.storeSettings(); - MainApp.bus().post(new EventRefreshGui()); - getPlugin().logPluginStatus(); - } + holder.checkboxVisible.setOnClickListener(v -> { + CheckBox cb = (CheckBox) v; + PluginBase plugin12 = (PluginBase) cb.getTag(); + plugin12.setFragmentVisible(type, cb.isChecked()); + ConfigBuilderPlugin.getPlugin().storeSettings(); + MainApp.bus().post(new EventRefreshGui()); + ConfigBuilderPlugin.getPlugin().logPluginStatus(); }); - holder.settings.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - final PluginBase plugin = (PluginBase) v.getTag(); - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - Intent i = new Intent(getContext(), PreferencesActivity.class); - i.putExtra("id", plugin.getPreferencesId()); - startActivity(i); - } - }, null); - } + holder.settings.setOnClickListener(v -> { + final PluginBase plugin13 = (PluginBase) v.getTag(); + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(getContext(), PreferencesActivity.class); + i.putExtra("id", plugin13.getPreferencesId()); + startActivity(i); + }, null); }); - holder.name.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - final PluginBase plugin = (PluginBase) v.getTag(); - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - Intent i = new Intent(getContext(), PreferencesActivity.class); - i.putExtra("id", plugin.getPreferencesId()); - startActivity(i); - } - }, null); - return false; - } + holder.name.setOnLongClickListener(v -> { + final PluginBase plugin14 = (PluginBase) v.getTag(); + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(getContext(), PreferencesActivity.class); + i.putExtra("id", plugin14.getPreferencesId()); + startActivity(i); + }, null); + return false; }); } else { @@ -316,8 +294,8 @@ public class ConfigBuilderFragment extends Fragment { if (type == PluginBase.INSULIN || type == PluginBase.PUMP || type == PluginBase.TREATMENT || type == PluginBase.PROFILE || type == PluginBase.SENSITIVITY) if (pluginList.size() < 2) { holder.checkboxEnabled.setEnabled(false); - plugin.setFragmentEnabled(type, true); - getPlugin().storeSettings(); + plugin.setPluginEnabled(type, true); + ConfigBuilderPlugin.getPlugin().storeSettings(); } // Constraints cannot be disabled @@ -390,23 +368,23 @@ public class ConfigBuilderFragment extends Fragment { if (p.getName().equals(changedPlugin.getName())) { // this is new selected } else { - p.setFragmentEnabled(type, false); + p.setPluginEnabled(type, false); p.setFragmentVisible(type, false); } } } else { // enable first plugin in list if (type == PluginBase.PUMP) - MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setFragmentEnabled(type, true); + VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.INSULIN) - MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setFragmentEnabled(type, true); + InsulinFastactingPlugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.SENSITIVITY) - MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setFragmentEnabled(type, true); + SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.PROFILE) - MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(type, true); + NSProfilePlugin.getPlugin().setPluginEnabled(type, true); else - pluginsInCategory.get(0).setFragmentEnabled(type, true); + pluginsInCategory.get(0).setPluginEnabled(type, true); } - setViews(); + updateGUI(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java index e0a8155ffa..51d91732ca 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java @@ -4,14 +4,15 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.annotation.Nullable; -import org.json.JSONException; -import org.json.JSONObject; +import com.crashlytics.android.answers.CustomEvent; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; @@ -22,6 +23,7 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; +import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.ExtendedBolus; @@ -33,7 +35,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.ConstraintsInterface; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; @@ -43,22 +45,29 @@ 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; import info.nightscout.androidaps.queue.CommandQueue; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; -import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; /** * Created by mike on 05.08.2016. */ -public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, TreatmentsInterface { +public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { private static Logger log = LoggerFactory.getLogger(ConfigBuilderPlugin.class); - private static BgSourceInterface activeBgSource; + private static ConfigBuilderPlugin configBuilderPlugin; + + static public ConfigBuilderPlugin getPlugin() { + if (configBuilderPlugin == null) + configBuilderPlugin = new ConfigBuilderPlugin(); + return configBuilderPlugin; + } + + private BgSourceInterface activeBgSource; private static PumpInterface activePump; private static ProfileInterface activeProfile; private static TreatmentsInterface activeTreatments; @@ -132,7 +141,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { // Always enabled } @@ -182,7 +191,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr String settingEnabled = "ConfigBuilder_" + type + "_" + p.getClass().getSimpleName() + "_Enabled"; String settingVisible = "ConfigBuilder_" + type + "_" + p.getClass().getSimpleName() + "_Visible"; if (SP.contains(settingEnabled)) - p.setFragmentEnabled(type, SP.getBoolean(settingEnabled, true)); + p.setPluginEnabled(type, SP.getBoolean(settingEnabled, true)); if (SP.contains(settingVisible)) p.setFragmentVisible(type, SP.getBoolean(settingVisible, true) && SP.getBoolean(settingEnabled, true)); } catch (Exception e) { @@ -197,7 +206,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr return commandQueue; } - public static BgSourceInterface getActiveBgSource() { + public BgSourceInterface getActiveBgSource() { return activeBgSource; } @@ -342,7 +351,7 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr found = p; } else if (p.isEnabled(type)) { // set others disabled - p.setFragmentEnabled(type, false); + p.setPluginEnabled(type, false); } } // If none enabled, enable first one @@ -355,10 +364,14 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr * expect absolute request and allow both absolute and percent response based on pump capabilities */ public void applyTBRRequest(APSResult request, Profile profile, Callback callback) { - PumpInterface pump = getActivePump(); - request.rate = applyBasalConstraints(request.rate); + if (!request.tempBasalRequested) { + return; + } - long now = System.currentTimeMillis(); + PumpInterface pump = getActivePump(); + + request.rateConstraint = new Constraint<>(request.rate); + request.rate = MainApp.getConstraintChecker().applyBasalConstraints(request.rateConstraint, profile).value(); if (!pump.isInitialized()) { log.debug("applyAPSRequest: " + MainApp.sResources.getString(R.string.pumpNotInitialized)); @@ -379,37 +392,55 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr if (Config.logCongigBuilderActions) log.debug("applyAPSRequest: " + request.toString()); - if (request.tempBasalReqested) { - TemporaryBasal activeTemp = getTempBasalFromHistory(now); - if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) { - if (activeTemp != null) { - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: cancelTempBasal()"); - getCommandQueue().cancelTempBasal(false, callback); - } else { - if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: Basal set correctly"); - if (callback != null) { - callback.result(new PumpEnactResult().absolute(request.rate).duration(0).enacted(false).success(true).comment("Basal set correctly")).run(); - } - } - } else if (activeTemp != null - && activeTemp.getPlannedRemainingMinutes() > 5 - && Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) { + long now = System.currentTimeMillis(); + TemporaryBasal activeTemp = getTempBasalFromHistory(now); + if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) { + if (activeTemp != null) { if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: Temp basal set correctly"); - if (callback != null) { - callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile)).duration(activeTemp.getPlannedRemainingMinutes()).enacted(false).success(true).comment("Temp basal set correctly")).run(); - } + log.debug("applyAPSRequest: cancelTempBasal()"); + getCommandQueue().cancelTempBasal(false, callback); } else { if (Config.logCongigBuilderActions) - log.debug("applyAPSRequest: setTempBasalAbsolute()"); - getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, callback); + log.debug("applyAPSRequest: Basal set correctly"); + if (callback != null) { + callback.result(new PumpEnactResult().absolute(request.rate).duration(0) + .enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run(); + } } + } else if (activeTemp != null + && activeTemp.getPlannedRemainingMinutes() > 5 + && request.duration - activeTemp.getPlannedRemainingMinutes() < 30 + && Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) { + if (Config.logCongigBuilderActions) + log.debug("applyAPSRequest: Temp basal set correctly"); + if (callback != null) { + callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile)) + .enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes()) + .comment(MainApp.gs(R.string.let_temp_basal_run))).run(); + } + } else { + if (Config.logCongigBuilderActions) + log.debug("applyAPSRequest: setTempBasalAbsolute()"); + getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback); } } public void applySMBRequest(APSResult request, Callback callback) { + if (!request.bolusRequested) { + return; + } + + long lastBolusTime = getLastBolusTime(); + if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { + log.debug("SMB requested but still in 3 min interval"); + if (callback != null) { + callback.result(new PumpEnactResult() + .comment(MainApp.gs(R.string.smb_frequency_exceeded)) + .enacted(false).success(false)).run(); + } + return; + } + PumpInterface pump = getActivePump(); if (!pump.isInitialized()) { @@ -431,148 +462,16 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr if (Config.logCongigBuilderActions) log.debug("applySMBRequest: " + request.toString()); - if (request.bolusRequested) { - long lastBolusTime = getLastBolusTime(); - if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { - log.debug("SMB requsted but still in 3 min interval"); - } else { - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; - detailedBolusInfo.insulin = request.smb; - detailedBolusInfo.isSMB = true; - detailedBolusInfo.source = Source.USER; - detailedBolusInfo.deliverAt = request.deliverAt; - getCommandQueue().bolus(detailedBolusInfo, callback); - } - } - } - - /** - * Constraints interface - **/ - @Override - public boolean isLoopEnabled() { - boolean result = true; - - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - result = result && constrain.isLoopEnabled(); - } - return result; - } - - @Override - public boolean isClosedModeEnabled() { - boolean result = true; - - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - result = result && constrain.isClosedModeEnabled(); - } - return result; - } - - @Override - public boolean isAutosensModeEnabled() { - boolean result = true; - - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - result = result && constrain.isAutosensModeEnabled(); - } - return result; - } - - @Override - public boolean isAMAModeEnabled() { - boolean result = SP.getBoolean("openapsama_useautosens", false); - - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - result = result && constrain.isAMAModeEnabled(); - } - return result; - } - - @Override - public boolean isSMBModeEnabled() { - boolean result = true; // TODO update for SMB // SP.getBoolean("openapsama_useautosens", false); - - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - result = result && constrain.isSMBModeEnabled(); - } - return result; - } - - @Override - public Double applyBasalConstraints(Double absoluteRate) { - Double rateAfterConstrain = absoluteRate; - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - rateAfterConstrain = Math.min(constrain.applyBasalConstraints(absoluteRate), rateAfterConstrain); - } - return rateAfterConstrain; - } - - @Override - public Integer applyBasalConstraints(Integer percentRate) { - Integer rateAfterConstrain = percentRate; - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - rateAfterConstrain = Math.min(constrain.applyBasalConstraints(percentRate), rateAfterConstrain); - } - return rateAfterConstrain; - } - - @Override - public Double applyBolusConstraints(Double insulin) { - Double insulinAfterConstrain = insulin; - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - insulinAfterConstrain = Math.min(constrain.applyBolusConstraints(insulin), insulinAfterConstrain); - } - return insulinAfterConstrain; - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - Integer carbsAfterConstrain = carbs; - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - carbsAfterConstrain = Math.min(constrain.applyCarbsConstraints(carbs), carbsAfterConstrain); - } - return carbsAfterConstrain; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - Double maxIobAfterConstrain = maxIob; - ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); - for (PluginBase p : constraintsPlugins) { - ConstraintsInterface constrain = (ConstraintsInterface) p; - if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; - maxIobAfterConstrain = Math.min(constrain.applyMaxIOBConstraints(maxIob), maxIobAfterConstrain); - } - return maxIobAfterConstrain; + // deliver SMB + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; + detailedBolusInfo.insulin = request.smb; + detailedBolusInfo.isSMB = true; + detailedBolusInfo.source = Source.USER; + detailedBolusInfo.deliverAt = request.deliverAt; + if (Config.logCongigBuilderActions) + log.debug("applyAPSRequest: bolus()"); + getCommandQueue().bolus(detailedBolusInfo, callback); } // ****** Treatments interface ***** @@ -767,9 +666,12 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr if (profileSwitch.profileJson != null) { return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; } else { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profileSwitch.profileName; + ProfileStore profileStore = activeProfile.getProfile(); + if (profileStore != null) { + Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profileSwitch.profileName; + } } } return MainApp.gs(R.string.noprofileselected); @@ -806,13 +708,21 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr return profile; } } + if (getProfileSwitchesFromHistory().size() > 0) { + FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("time", time) + .putCustomAttribute("getProfileSwitchesFromHistory", getProfileSwitchesFromHistory().toString()) + ); + } log.debug("getProfile at the end: returning null"); 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) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java index 3b0891680d..e031d16976 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesPlugin.java @@ -10,18 +10,18 @@ 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.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.utils.SP; @@ -67,7 +67,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { @Override public String getNameShort() { - String name = MainApp.sResources.getString(R.string.objectives_shortname); + String name = MainApp.gs(R.string.objectives_shortname); if (!name.trim().isEmpty()) { //only if translation exists return name; @@ -102,7 +102,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { } @Override @@ -115,7 +115,7 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { return -1; } - class Objective { + public class Objective { Integer num; String objective; String gate; @@ -131,6 +131,18 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { this.durationInDays = durationInDays; this.accomplished = accomplished; } + + public void setStarted(Date started) { + this.started = started; + } + + boolean isStarted() { + return started.getTime() > 0; + } + + boolean isFinished() { + return accomplished.getTime() != 0; + } } // Objective 0 @@ -168,27 +180,28 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginBase.APS)) apsEnabled = true; - return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientInternalPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded, - MainApp.sResources.getString(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS) - + "\n" + MainApp.sResources.getString(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientInternalPlugin.getPlugin().hasWritePermission()) - + (isVirtualPump ? "\n" + MainApp.sResources.getString(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "") - + "\n" + MainApp.sResources.getString(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS) - + "\n" + MainApp.sResources.getString(R.string.hasbgdata) + ": " + yesOrNo(hasBGData) - + "\n" + MainApp.sResources.getString(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP)) - + "\n" + MainApp.sResources.getString(R.string.apsselected) + ": " + yesOrNo(apsEnabled) + return new RequirementResult(hasBGData && bgIsAvailableInNS && pumpStatusIsAvailableInNS && NSClientPlugin.getPlugin().hasWritePermission() && LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP) && apsEnabled && vpUploadNeeded, + MainApp.gs(R.string.objectives_bgavailableinns) + ": " + yesOrNo(bgIsAvailableInNS) + + "\n" + MainApp.gs(R.string.nsclienthaswritepermission) + ": " + yesOrNo(NSClientPlugin.getPlugin().hasWritePermission()) + + (isVirtualPump ? "\n" + MainApp.gs(R.string.virtualpump_uploadstatus_title) + ": " + yesOrNo(vpUploadEnabled) : "") + + "\n" + MainApp.gs(R.string.objectives_pumpstatusavailableinns) + ": " + yesOrNo(pumpStatusIsAvailableInNS) + + "\n" + MainApp.gs(R.string.hasbgdata) + ": " + yesOrNo(hasBGData) + + "\n" + MainApp.gs(R.string.loopenabled) + ": " + yesOrNo(LoopPlugin.getPlugin().isEnabled(PluginBase.LOOP)) + + "\n" + MainApp.gs(R.string.apsselected) + ": " + yesOrNo(apsEnabled) ); case 1: return new RequirementResult(manualEnacts >= manualEnactsNeeded, - MainApp.sResources.getString(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded); + MainApp.gs(R.string.objectives_manualenacts) + ": " + manualEnacts + "/" + manualEnactsNeeded); case 2: return new RequirementResult(true, ""); case 3: - boolean closedModeEnabled = SafetyPlugin.getPlugin().isClosedModeEnabled(); - return new RequirementResult(closedModeEnabled, MainApp.sResources.getString(R.string.closedmodeenabled) + ": " + yesOrNo(closedModeEnabled)); + Constraint closedLoopEnabled = new Constraint<>(true); + SafetyPlugin.getPlugin().isClosedLoopAllowed(closedLoopEnabled); + return new RequirementResult(closedLoopEnabled.value(), MainApp.gs(R.string.closedmodeenabled) + ": " + yesOrNo(closedLoopEnabled.value())); case 4: - double maxIOB = MainApp.getConfigBuilder().applyMaxIOBConstraints(1000d); + double maxIOB = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); boolean maxIobSet = maxIOB > 0; - return new RequirementResult(maxIobSet, MainApp.sResources.getString(R.string.maxiobset) + ": " + yesOrNo(maxIobSet)); + return new RequirementResult(maxIobSet, MainApp.gs(R.string.maxiobset) + ": " + yesOrNo(maxIobSet)); default: return new RequirementResult(true, ""); } @@ -202,49 +215,49 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { objectives = new ArrayList<>(); objectives.add(new Objective(0, - MainApp.sResources.getString(R.string.objectives_0_objective), - MainApp.sResources.getString(R.string.objectives_0_gate), + MainApp.gs(R.string.objectives_0_objective), + MainApp.gs(R.string.objectives_0_gate), new Date(0), 0, // 0 day new Date(0))); objectives.add(new Objective(1, - MainApp.sResources.getString(R.string.objectives_1_objective), - MainApp.sResources.getString(R.string.objectives_1_gate), + MainApp.gs(R.string.objectives_1_objective), + MainApp.gs(R.string.objectives_1_gate), new Date(0), 7, // 7 days new Date(0))); objectives.add(new Objective(2, - MainApp.sResources.getString(R.string.objectives_2_objective), - MainApp.sResources.getString(R.string.objectives_2_gate), + MainApp.gs(R.string.objectives_2_objective), + MainApp.gs(R.string.objectives_2_gate), new Date(0), 0, // 0 days new Date(0))); objectives.add(new Objective(3, - MainApp.sResources.getString(R.string.objectives_3_objective), - MainApp.sResources.getString(R.string.objectives_3_gate), + MainApp.gs(R.string.objectives_3_objective), + MainApp.gs(R.string.objectives_3_gate), new Date(0), 5, // 5 days new Date(0))); objectives.add(new Objective(4, - MainApp.sResources.getString(R.string.objectives_4_objective), - MainApp.sResources.getString(R.string.objectives_4_gate), + MainApp.gs(R.string.objectives_4_objective), + MainApp.gs(R.string.objectives_4_gate), new Date(0), 1, new Date(0))); objectives.add(new Objective(5, - MainApp.sResources.getString(R.string.objectives_5_objective), - MainApp.sResources.getString(R.string.objectives_5_gate), + MainApp.gs(R.string.objectives_5_objective), + MainApp.gs(R.string.objectives_5_gate), new Date(0), 7, new Date(0))); objectives.add(new Objective(6, - MainApp.sResources.getString(R.string.objectives_6_objective), + MainApp.gs(R.string.objectives_6_objective), "", new Date(0), 28, new Date(0))); objectives.add(new Objective(7, - MainApp.sResources.getString(R.string.objectives_7_objective), + MainApp.gs(R.string.objectives_7_objective), "", new Date(0), 28, @@ -294,60 +307,45 @@ public class ObjectivesPlugin implements PluginBase, ConstraintsInterface { * Constraints interface **/ @Override - public boolean isLoopEnabled() { - return objectives.get(0).started.getTime() > 0; + public Constraint isLoopInvokationAllowed(Constraint value) { + if (!objectives.get(0).isStarted()) + value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 1), this); + return value; } @Override - public boolean isClosedModeEnabled() { - return objectives.get(3).started.getTime() > 0; + public Constraint isClosedLoopAllowed(Constraint value) { + if (!objectives.get(3).isStarted()) + value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 4), this); + return value; } @Override - public boolean isAutosensModeEnabled() { - return objectives.get(5).started.getTime() > 0; + public Constraint isAutosensModeEnabled(Constraint value) { + if (!objectives.get(5).isStarted()) + value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 6), this); + return value; } @Override - public boolean isAMAModeEnabled() { - return objectives.get(6).started.getTime() > 0; + public Constraint isAMAModeEnabled(Constraint value) { + if (!objectives.get(6).isStarted()) + value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 7), this); + return value; } @Override - public boolean isSMBModeEnabled() { - return objectives.get(7).started.getTime() > 0; + public Constraint isSMBModeEnabled(Constraint value) { + if (!objectives.get(7).isStarted()) + value.set(false, String.format(MainApp.gs(R.string.objectivenotstarted), 8), this); + return value; } @Override - public Double applyMaxIOBConstraints(Double maxIob) { - if (objectives.get(3).started.getTime() > 0 && objectives.get(3).accomplished.getTime() == 0) { - if (Config.logConstraintsChanges) - log.debug("Limiting maxIOB " + maxIob + " to " + 0 + "U"); - return 0d; - } else { - return maxIob; - } + public Constraint applyMaxIOBConstraints(Constraint maxIob) { + if (objectives.get(3).isStarted() && !objectives.get(3).isFinished()) + maxIob.set(0d, String.format(MainApp.gs(R.string.objectivenotfinished), 4), this); + return maxIob; } - @Override - public Double applyBasalConstraints(Double absoluteRate) { - return absoluteRate; - } - - @Override - public Integer applyBasalConstraints(Integer percentRate) { - return percentRate; - } - - @Override - public Double applyBolusConstraints(Double insulin) { - return insulin; - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java index 41a7c1eb00..e76be9a32c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java @@ -3,17 +3,19 @@ package info.nightscout.androidaps.plugins.ConstraintsSafety; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Objects; - -import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.ConstraintChecker; import info.nightscout.androidaps.data.Profile; +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.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; +import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; +import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; +import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.HardLimits; import info.nightscout.utils.Round; import info.nightscout.utils.SP; @@ -79,7 +81,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { } @@ -92,142 +94,133 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface { return R.xml.pref_safety; } - @Override - public boolean isLoopEnabled() { - return ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; - } - /** * Constraints interface **/ @Override - public boolean isClosedModeEnabled() { - if (!MainApp.isEngineeringModeOrRelease()) return false; + public Constraint isLoopInvokationAllowed(Constraint value) { + if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) + value.set(false, MainApp.gs(R.string.pumpisnottempbasalcapable), this); + return value; + } + + @Override + public Constraint isClosedLoopAllowed(Constraint value) { + if (!MainApp.isEngineeringModeOrRelease()) + value.set(false, MainApp.gs(R.string.closed_loop_disabled_on_dev_branch), this); + String mode = SP.getString("aps_mode", "open"); - return mode.equals("closed") && BuildConfig.CLOSEDLOOP; + if (!mode.equals("closed")) + value.set(false, MainApp.gs(R.string.closedmodedisabledinpreferences), this); + return value; } @Override - public boolean isAutosensModeEnabled() { - return true; + public Constraint isAutosensModeEnabled(Constraint value) { + boolean enabled = SP.getBoolean(R.string.key_openapsama_useautosens, false); + if (!enabled) + value.set(false, MainApp.gs(R.string.autosensdisabledinpreferences), this); + return value; } @Override - public boolean isAMAModeEnabled() { - return true; + public Constraint isSMBModeEnabled(Constraint value) { + boolean enabled = SP.getBoolean(R.string.key_use_smb, false); + if (!enabled) + value.set(false, MainApp.gs(R.string.smbdisabledinpreferences), this); + ConstraintChecker constraintChecker = MainApp.getConstraintChecker(); + Constraint closedLoop = constraintChecker.isClosedLoopAllowed(); + if (!closedLoop.value()) + value.set(false, MainApp.gs(R.string.smbnotallowedinopenloopmode), this); + return value; } @Override - public boolean isSMBModeEnabled() { - return true; + public Constraint isAdvancedFilteringEnabled(Constraint value) { + BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource(); + + if (bgSource != null) { + if (!bgSource.advancedFilteringSupported()) + value.set(false, MainApp.gs(R.string.smbalwaysdisabled), this); + } + return value; } @Override - public Double applyBasalConstraints(Double absoluteRate) { - Double origAbsoluteRate = absoluteRate; - Double maxBasal = SP.getDouble("openapsma_max_basal", 1d); + public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { - Profile profile = MainApp.getConfigBuilder().getProfile(); - if (profile == null) return absoluteRate; - if (absoluteRate < 0) absoluteRate = 0d; + absoluteRate.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbasalratio), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this); + + double maxBasal = SP.getDouble(R.string.key_openapsma_max_basal, 1d); + absoluteRate.setIfSmaller(maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), maxBasal, MainApp.gs(R.string.maxvalueinpreferences)), this); - Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d); - Integer maxBasalFromDaily = SP.getInt("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 && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - 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 && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origRate + " by maxBasalMult to " + absoluteRate + "U/h"); - } - if (absoluteRate > profile.getMaxDailyBasal() * maxBasalFromDaily) { - absoluteRate = profile.getMaxDailyBasal() * maxBasalFromDaily; - if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origRate + " by 3 * maxDailyBasal to " + absoluteRate + "U/h"); - } + Double maxBasalMult = SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d); + double maxFromBasalMult = Math.floor(maxBasalMult * profile.getBasal() * 100) / 100; + absoluteRate.setIfSmaller(maxFromBasalMult, String.format(MainApp.gs(R.string.limitingbasalratio), maxFromBasalMult, MainApp.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(maxFromDaily, String.format(MainApp.gs(R.string.limitingbasalratio), maxFromDaily, MainApp.gs(R.string.maxdailybasalmultiplier)), this); + + absoluteRate.setIfSmaller(HardLimits.maxBasal(), String.format(MainApp.gs(R.string.limitingbasalratio), HardLimits.maxBasal(), MainApp.gs(R.string.hardlimit)), this); return absoluteRate; } @Override - public Integer applyBasalConstraints(Integer percentRate) { - Integer origPercentRate = percentRate; - Double maxBasal = SP.getDouble("openapsma_max_basal", 1d); + public Constraint applyBasalPercentConstraints(Constraint 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.addReason("Percent rate " + percentRate.originalValue() + "% recalculated to " + DecimalFormatter.to2Decimal(absoluteRate) + " U/h with current basal " + DecimalFormatter.to2Decimal(currentBasal) + " U/h", this); - if (Config.logConstraintsChanges) - log.debug("Percent rate " + percentRate + "% recalculated to " + absoluteRate + "U/h with current basal " + currentBasal + "U/h"); + Constraint absoluteConstraint = new Constraint<>(absoluteRate); + applyBasalConstraints(absoluteConstraint, profile); + percentRate.copyReasons(absoluteConstraint); - if (absoluteRate < 0) absoluteRate = 0d; - - Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d); - Integer maxBasalFromDaily = SP.getInt("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)), this); + + return percentRate; } @Override - public Double applyBolusConstraints(Double insulin) { - try { - Double maxBolus = SP.getDouble("treatmentssafety_maxbolus", 3d); + public Constraint applyBolusConstraints(Constraint insulin) { + insulin.setIfGreater(0d, String.format(MainApp.gs(R.string.limitingbolus), 0d, MainApp.gs(R.string.itmustbepositivevalue)), this); - if (insulin < 0) insulin = 0d; - if (insulin > maxBolus) insulin = maxBolus; - } catch (Exception e) { - insulin = 0d; - } - if (insulin > HardLimits.maxBolus()) insulin = HardLimits.maxBolus(); + Double maxBolus = SP.getDouble(R.string.key_treatmentssafety_maxbolus, 3d); + insulin.setIfSmaller(maxBolus, String.format(MainApp.gs(R.string.limitingbolus), maxBolus, MainApp.gs(R.string.maxvalueinpreferences)), this); + + insulin.setIfSmaller(HardLimits.maxBolus(), String.format(MainApp.gs(R.string.limitingbolus), HardLimits.maxBolus(), MainApp.gs(R.string.hardlimit)), this); return insulin; } @Override - public Integer applyCarbsConstraints(Integer carbs) { - try { - Integer maxCarbs = SP.getInt("treatmentssafety_maxcarbs", 48); + public Constraint applyCarbsConstraints(Constraint carbs) { + carbs.setIfGreater(0, String.format(MainApp.gs(R.string.limitingcarbs), 0, MainApp.gs(R.string.itmustbepositivevalue)), this); + + Integer maxCarbs = SP.getInt(R.string.key_treatmentssafety_maxcarbs, 48); + carbs.setIfSmaller(maxCarbs, String.format(MainApp.gs(R.string.limitingcarbs), maxCarbs, MainApp.gs(R.string.maxvalueinpreferences)), this); - if (carbs < 0) carbs = 0; - if (carbs > maxCarbs) carbs = maxCarbs; - } catch (Exception e) { - carbs = 0; - } return carbs; } @Override - public Double applyMaxIOBConstraints(Double maxIob) { + public Constraint applyMaxIOBConstraints(Constraint maxIob) { + double maxIobPref = SP.getDouble(R.string.key_openapsma_max_iob, 1.5d); + maxIob.setIfSmaller(maxIobPref, String.format(MainApp.gs(R.string.limitingiob), maxIobPref, MainApp.gs(R.string.maxvalueinpreferences)), this); + + if (OpenAPSMAPlugin.getPlugin().isEnabled(PluginBase.APS)) + maxIob.setIfSmaller(HardLimits.maxIobAMA(), String.format(MainApp.gs(R.string.limitingiob), HardLimits.maxIobAMA(), MainApp.gs(R.string.hardlimit)), this); + if (OpenAPSAMAPlugin.getPlugin().isEnabled(PluginBase.APS)) + maxIob.setIfSmaller(HardLimits.maxIobAMA(), String.format(MainApp.gs(R.string.limitingiob), HardLimits.maxIobAMA(), MainApp.gs(R.string.hardlimit)), this); + if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) + maxIob.setIfSmaller(HardLimits.maxIobSMB(), String.format(MainApp.gs(R.string.limitingiob), HardLimits.maxIobSMB(), MainApp.gs(R.string.hardlimit)), this); return maxIob; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java index 64517a19a5..2f7337566e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodPlugin.java @@ -73,7 +73,7 @@ public class FoodPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingPlugin.java index 6218a2ecfe..bb9c035115 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingPlugin.java @@ -71,7 +71,7 @@ public class InsulinFastactingPlugin implements PluginBase, InsulinInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == INSULIN) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingProlongedPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingProlongedPlugin.java index d336786f49..6afb867ec9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingProlongedPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFastactingProlongedPlugin.java @@ -72,7 +72,7 @@ public class InsulinFastactingProlongedPlugin implements PluginBase, InsulinInte } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == INSULIN) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java index 3cc2e6b9ca..76667d3ad7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefFreePeakPlugin.java @@ -59,7 +59,7 @@ public class InsulinOrefFreePeakPlugin extends InsulinOrefBasePlugin { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == INSULIN) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java index cae9ac540d..86af7f8130 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefRapidActingPlugin.java @@ -58,7 +58,7 @@ public class InsulinOrefRapidActingPlugin extends InsulinOrefBasePlugin { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == INSULIN) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java index 0d390a3ba2..0c24bb1034 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinOrefUltraRapidActingPlugin.java @@ -58,7 +58,7 @@ public class InsulinOrefUltraRapidActingPlugin extends InsulinOrefBasePlugin { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == INSULIN) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java index dddea570be..7a79b62c3a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java @@ -64,7 +64,8 @@ public class AutosensData { public double slopeFromMaxDeviation = 0; public double slopeFromMinDeviation = 999; - public String log(long time) { + @Override + public String toString() { return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java index 19b8e492d6..0009287354 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java @@ -117,7 +117,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { } @@ -531,8 +531,6 @@ public class IobCobCalculatorPlugin implements PluginBase { @Subscribe public void onEventNewBG(EventNewBG ev) { - if (!ev.isFromActiveBgSource) - return; if (this != getPlugin()) { log.debug("Ignoring event for non default instance"); return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index 1a4c499c59..5da63ad2f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -4,6 +4,9 @@ import android.content.Context; import android.os.PowerManager; import android.support.v4.util.LongSparseArray; +import com.crashlytics.android.Crashlytics; +import com.crashlytics.android.answers.CustomEvent; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,6 +14,7 @@ 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.Constants; import info.nightscout.androidaps.MainApp; @@ -22,6 +26,7 @@ import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.queue.QueueThread; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; /** * Created by mike on 23.01.2018. @@ -151,21 +156,34 @@ public class IobCobThread extends Thread { AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); if (hourAgoData != null) { int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); + log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()); + int past = 1; + try { + for (; past < 12; past++) { + AutosensData ad = autosensDataTable.valueAt(initialIndex + past); + double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; + if (ad.avgDeviation > maxDeviation) { + slopeFromMaxDeviation = Math.min(0, deviationSlope); + maxDeviation = ad.avgDeviation; + } + if (ad.avgDeviation < minDeviation) { + slopeFromMinDeviation = Math.max(0, deviationSlope); + minDeviation = ad.avgDeviation; + } - for (int past = 1; past < 12; past++) { - AutosensData ad = autosensDataTable.valueAt(initialIndex + past); - double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; - if (ad.avgDeviation > maxDeviation) { - slopeFromMaxDeviation = Math.min(0, deviationSlope); - maxDeviation = ad.avgDeviation; + //if (Config.logAutosensData) + // log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); } - if (ad.avgDeviation < minDeviation) { - slopeFromMinDeviation = Math.max(0, deviationSlope); - minDeviation = ad.avgDeviation; - } - - //if (Config.logAutosensData) - // log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); + } catch (Exception e) { + log.error("Unhandled exception", e); + FabricPrivacy.logException(e); + FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("autosensDataTable", iobCobCalculatorPlugin.getAutosensDataTable().toString()) + .putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()) + .putCustomAttribute("past", past) + ); } } } @@ -228,7 +246,7 @@ public class IobCobThread extends Thread { log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime)); autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio; if (Config.logAutosensData) - log.debug(autosensData.log(bgTime)); + log.debug(autosensData.toString()); } } MainApp.bus().post(new EventAutosensCalculationFinished(cause)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java index 8050aa7769..7a9c4deae9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java @@ -17,6 +17,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.utils.DecimalFormatter; @@ -31,7 +32,7 @@ public class APSResult { public String reason; public double rate; public int duration; - public boolean tempBasalReqested = false; + public boolean tempBasalRequested = false; public boolean bolusRequested = false; public IobTotal iob; public JSONObject json = new JSONObject(); @@ -39,6 +40,11 @@ public class APSResult { public double smb = 0d; // super micro bolus in units public long deliverAt = 0; + public Constraint inputConstraints; + + public Constraint rateConstraint; + public Constraint smbConstraint; + @Override public String toString() { final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); @@ -56,7 +62,7 @@ public class APSResult { // smb if (smb != 0) - ret += ("SMB: " + DecimalFormatter.to2Decimal(smb) + " U\n"); + ret += ("SMB: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U\n"); // reason ret += MainApp.sResources.getString(R.string.reason) + ": " + reason; @@ -76,12 +82,12 @@ public class APSResult { ret = MainApp.sResources.getString(R.string.let_temp_basal_run) + "
"; else ret = "" + MainApp.sResources.getString(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " + - "(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%)
" + - "" + MainApp.sResources.getString(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min
"; + "(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%)
" + + "" + MainApp.sResources.getString(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min
"; // smb if (smb != 0) - ret += ("" + "SMB" + ": " + DecimalFormatter.to2Decimal(smb) + " U
"); + ret += ("" + "SMB" + ": " + DecimalFormatter.toPumpSupportedBolus(smb) + " U
"); // reason ret += "" + MainApp.sResources.getString(R.string.reason) + ": " + reason.replace("<", "<").replace(">", ">"); @@ -98,9 +104,15 @@ public class APSResult { newResult.reason = reason; newResult.rate = rate; newResult.duration = duration; - newResult.tempBasalReqested = tempBasalReqested; + newResult.tempBasalRequested = tempBasalRequested; newResult.bolusRequested = bolusRequested; newResult.iob = iob; + newResult.json = json; + newResult.hasPredictions = hasPredictions; + newResult.smb = smb; + newResult.deliverAt = deliverAt; + newResult.rateConstraint = rateConstraint; + newResult.smbConstraint = smbConstraint; return newResult; } @@ -216,6 +228,6 @@ public class APSResult { } public boolean isChangeRequested() { - return tempBasalReqested || bolusRequested; + return tempBasalRequested || bolusRequested; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java index c9b60ab3d6..19ed6496e7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java @@ -20,6 +20,7 @@ import butterknife.ButterKnife; import butterknife.OnClick; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui; import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; @@ -40,6 +41,8 @@ public class LoopFragment extends SubscriberFragment { TextView requestView; @BindView(R.id.loop_constraintsprocessed) TextView constraintsProcessedView; + @BindView(R.id.loop_constraints) + TextView constraintsView; @BindView(R.id.loop_tbrsetbypump) TextView tbrSetByPumpView; @BindView(R.id.loop_smbsetbypump) @@ -85,14 +88,26 @@ public class LoopFragment extends SubscriberFragment { Activity activity = getActivity(); if (activity != null) activity.runOnUiThread(() -> { - if (LoopPlugin.lastRun != null) { - requestView.setText(LoopPlugin.lastRun.request != null ? LoopPlugin.lastRun.request.toSpanned() : ""); - constraintsProcessedView.setText(LoopPlugin.lastRun.constraintsProcessed != null ? LoopPlugin.lastRun.constraintsProcessed.toSpanned() : ""); - sourceView.setText(LoopPlugin.lastRun.source != null ? LoopPlugin.lastRun.source : ""); - lastRunView.setText(LoopPlugin.lastRun.lastAPSRun != null && LoopPlugin.lastRun.lastAPSRun.getTime() != 0 ? LoopPlugin.lastRun.lastAPSRun.toLocaleString() : ""); - lastEnactView.setText(LoopPlugin.lastRun.lastEnact != null && LoopPlugin.lastRun.lastEnact.getTime() != 0 ? LoopPlugin.lastRun.lastEnact.toLocaleString() : ""); - tbrSetByPumpView.setText(LoopPlugin.lastRun.tbrSetByPump != null ? LoopPlugin.lastRun.tbrSetByPump.toSpanned() : ""); - smbSetByPumpView.setText(LoopPlugin.lastRun.smbSetByPump != null ? LoopPlugin.lastRun.smbSetByPump.toSpanned() : ""); + LoopPlugin.LastRun lastRun = LoopPlugin.lastRun; + if (lastRun != null) { + requestView.setText(lastRun.request != null ? lastRun.request.toSpanned() : ""); + constraintsProcessedView.setText(lastRun.constraintsProcessed != null ? lastRun.constraintsProcessed.toSpanned() : ""); + sourceView.setText(lastRun.source != null ? lastRun.source : ""); + lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : ""); + lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : ""); + tbrSetByPumpView.setText(lastRun.tbrSetByPump != null ? lastRun.tbrSetByPump.toSpanned() : ""); + smbSetByPumpView.setText(lastRun.smbSetByPump != null ? lastRun.smbSetByPump.toSpanned() : ""); + + String constraints = ""; + if (lastRun.constraintsProcessed != null) { + Constraint allConstraints = new Constraint<>(0d); + if (lastRun.constraintsProcessed.rateConstraint != null) + allConstraints.copyReasons(lastRun.constraintsProcessed.rateConstraint); + if (lastRun.constraintsProcessed.smbConstraint != null) + allConstraints.copyReasons(lastRun.constraintsProcessed.smbConstraint); + constraints = allConstraints.getMostLimitedReasons(); + } + constraintsView.setText(constraints); } }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java index 5846140b1e..c2f765e47e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java @@ -23,13 +23,12 @@ 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.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui; @@ -47,7 +46,7 @@ import info.nightscout.utils.SP; public class LoopPlugin implements PluginBase { private static Logger log = LoggerFactory.getLogger(LoopPlugin.class); - private static LoopPlugin loopPlugin; + protected static LoopPlugin loopPlugin; public static LoopPlugin getPlugin() { if (loopPlugin == null) { @@ -56,7 +55,7 @@ public class LoopPlugin implements PluginBase { return loopPlugin; } - private boolean fragmentEnabled = false; + private boolean pluginEnabled = false; private boolean fragmentVisible = false; private long loopSuspendedTill = 0L; // end of manual loop suspend @@ -95,12 +94,12 @@ public class LoopPlugin implements PluginBase { @Override public String getName() { - return MainApp.instance().getString(R.string.loop); + return MainApp.instance().gs(R.string.loop); } @Override public String getNameShort() { - String name = MainApp.sResources.getString(R.string.loop_shortname); + String name = MainApp.gs(R.string.loop_shortname); if (!name.trim().isEmpty()) { //only if translation exists return name; @@ -112,7 +111,7 @@ public class LoopPlugin implements PluginBase { @Override public boolean isEnabled(int type) { boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; - return type == LOOP && fragmentEnabled && pumpCapable; + return type == LOOP && pluginEnabled && pumpCapable; } @Override @@ -137,8 +136,8 @@ public class LoopPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { - if (type == LOOP) this.fragmentEnabled = fragmentEnabled; + public void setPluginEnabled(int type, boolean pluginEnabled) { + if (type == LOOP) this.pluginEnabled = pluginEnabled; } @Override @@ -153,19 +152,15 @@ public class LoopPlugin implements PluginBase { @Subscribe public void onStatusEvent(final EventTreatmentChange ev) { - if (ev.treatment == null || !ev.treatment.isSMB){ + if (ev.treatment == null || !ev.treatment.isSMB) { invoke("EventTreatmentChange", true); } } @Subscribe public void onStatusEvent(final EventAutosensCalculationFinished ev) { - if (!(ev.cause instanceof EventNewBG)) - return; - - EventNewBG bgEv = (EventNewBG) ev.cause; - if (bgEv.isNew && bgEv.isFromActiveBgSource && bgEv.isCurrent()) { - invoke("New BG", true); + if (ev.cause instanceof EventNewBG) { + invoke(ev.getClass().getSimpleName() + "(" + ev.cause.getClass().getSimpleName() + ")", true); } } @@ -260,10 +255,12 @@ 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))); + Constraint loopEnabled = MainApp.getConstraintChecker().isLoopInvokationAllowed(); + + if (!loopEnabled.value()) { + 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 +294,10 @@ 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.rateConstraint = new Constraint<>(resultAfterConstraints.rate); + resultAfterConstraints.rate = MainApp.getConstraintChecker().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value(); + resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb); + resultAfterConstraints.smb = MainApp.getConstraintChecker().applyBolusConstraints(resultAfterConstraints.smbConstraint).value(); // safety check for multiple SMBs long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime(); @@ -329,11 +328,16 @@ public class LoopPlugin implements PluginBase { return; } - if (constraintsInterface.isClosedModeEnabled()) { + Constraint closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed(); + + if (closedLoopEnabled.value()) { if (result.isChangeRequested()) { final PumpEnactResult waiting = new PumpEnactResult(); waiting.queued = true; - lastRun.tbrSetByPump = waiting; + if (resultAfterConstraints.tempBasalRequested) + lastRun.tbrSetByPump = waiting; + if (resultAfterConstraints.bolusRequested) + lastRun.smbSetByPump = waiting; MainApp.bus().post(new EventLoopUpdateGui()); FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest")); MainApp.getConfigBuilder().applyTBRRequest(resultAfterConstraints, profile, new Callback() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java similarity index 86% rename from app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java rename to app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java index a06850e1b1..39e24f8b38 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java @@ -7,7 +7,6 @@ import android.content.Context; import android.content.DialogInterface; import android.graphics.Paint; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.text.Html; import android.text.Spanned; import android.view.LayoutInflater; @@ -34,8 +33,8 @@ import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientU import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; -public class NSClientInternalFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { - private static Logger log = LoggerFactory.getLogger(NSClientInternalFragment.class); +public class NSClientFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { + private static Logger log = LoggerFactory.getLogger(NSClientFragment.class); private TextView logTextView; private TextView queueTextView; @@ -58,10 +57,10 @@ public class NSClientInternalFragment extends SubscriberFragment implements View logScrollview = (ScrollView) view.findViewById(R.id.nsclientinternal_logscrollview); autoscrollCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_autoscroll); - autoscrollCheckbox.setChecked(NSClientInternalPlugin.getPlugin().autoscroll); + autoscrollCheckbox.setChecked(NSClientPlugin.getPlugin().autoscroll); autoscrollCheckbox.setOnCheckedChangeListener(this); pausedCheckbox = (CheckBox) view.findViewById(R.id.nsclientinternal_paused); - pausedCheckbox.setChecked(NSClientInternalPlugin.getPlugin().paused); + pausedCheckbox.setChecked(NSClientPlugin.getPlugin().paused); pausedCheckbox.setOnCheckedChangeListener(this); logTextView = (TextView) view.findViewById(R.id.nsclientinternal_log); queueTextView = (TextView) view.findViewById(R.id.nsclientinternal_queue); @@ -101,11 +100,11 @@ public class NSClientInternalFragment extends SubscriberFragment implements View FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientRestart")); break; case R.id.nsclientinternal_delivernow: - NSClientInternalPlugin.getPlugin().resend("GUI"); + NSClientPlugin.getPlugin().resend("GUI"); FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientDeliverNow")); break; case R.id.nsclientinternal_clearlog: - NSClientInternalPlugin.getPlugin().clearLog(); + NSClientPlugin.getPlugin().clearLog(); break; case R.id.nsclientinternal_clearqueue: final Context context = getContext(); @@ -124,7 +123,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View builder.show(); break; case R.id.nsclientinternal_showqueue: - MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientInternalPlugin.getPlugin().queue().textList())); + MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientPlugin.getPlugin().queue().textList())); FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientShowQueue")); break; } @@ -135,14 +134,14 @@ public class NSClientInternalFragment extends SubscriberFragment implements View switch (buttonView.getId()) { case R.id.nsclientinternal_paused: SP.putBoolean(R.string.key_nsclientinternal_paused, isChecked); - NSClientInternalPlugin.getPlugin().paused = isChecked; + NSClientPlugin.getPlugin().paused = isChecked; MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); updateGUI(); FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause")); break; case R.id.nsclientinternal_autoscroll: SP.putBoolean(R.string.key_nsclientinternal_autoscroll, isChecked); - NSClientInternalPlugin.getPlugin().autoscroll = isChecked; + NSClientPlugin.getPlugin().autoscroll = isChecked; updateGUI(); break; } @@ -160,15 +159,15 @@ public class NSClientInternalFragment extends SubscriberFragment implements View activity.runOnUiThread(new Runnable() { @Override public void run() { - NSClientInternalPlugin.updateLog(); - logTextView.setText(NSClientInternalPlugin.textLog); - if (NSClientInternalPlugin.getPlugin().autoscroll) { + NSClientPlugin.getPlugin().updateLog(); + logTextView.setText(NSClientPlugin.getPlugin().textLog); + if (NSClientPlugin.getPlugin().autoscroll) { logScrollview.fullScroll(ScrollView.FOCUS_DOWN); } - urlTextView.setText(NSClientInternalPlugin.getPlugin().url()); + urlTextView.setText(NSClientPlugin.getPlugin().url()); Spanned queuetext = Html.fromHtml(MainApp.sResources.getString(R.string.queue) + " " + UploadQueue.size() + ""); queueTextView.setText(queuetext); - statusTextView.setText(NSClientInternalPlugin.getPlugin().status); + statusTextView.setText(NSClientPlugin.getPlugin().status); } }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java similarity index 83% rename from app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java rename to app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java index a51ea18cc7..cf33e9dc41 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java @@ -31,25 +31,25 @@ import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientServ import info.nightscout.utils.SP; import info.nightscout.utils.ToastUtils; -public class NSClientInternalPlugin implements PluginBase { - private static Logger log = LoggerFactory.getLogger(NSClientInternalPlugin.class); +public class NSClientPlugin implements PluginBase { + private static Logger log = LoggerFactory.getLogger(NSClientPlugin.class); - static NSClientInternalPlugin nsClientInternalPlugin; + static NSClientPlugin nsClientPlugin; - static public NSClientInternalPlugin getPlugin() { - if (nsClientInternalPlugin == null) { - nsClientInternalPlugin = new NSClientInternalPlugin(); + static public NSClientPlugin getPlugin() { + if (nsClientPlugin == null) { + nsClientPlugin = new NSClientPlugin(); } - return nsClientInternalPlugin; + return nsClientPlugin; } private boolean fragmentEnabled = true; private boolean fragmentVisible = true; - static public Handler handler; + public Handler handler; - private static List listLog = new ArrayList<>(); - static Spanned textLog = Html.fromHtml(""); + private final List listLog = new ArrayList<>(); + Spanned textLog = Html.fromHtml(""); public boolean paused = false; boolean autoscroll = true; @@ -58,13 +58,13 @@ public class NSClientInternalPlugin implements PluginBase { public NSClientService nsClientService = null; - NSClientInternalPlugin() { + NSClientPlugin() { MainApp.bus().register(this); paused = SP.getBoolean(R.string.key_nsclientinternal_paused, false); autoscroll = SP.getBoolean(R.string.key_nsclientinternal_autoscroll, true); if (handler == null) { - HandlerThread handlerThread = new HandlerThread(NSClientInternalPlugin.class.getSimpleName() + "Handler"); + HandlerThread handlerThread = new HandlerThread(NSClientPlugin.class.getSimpleName() + "Handler"); handlerThread.start(); handler = new Handler(handlerThread.getLooper()); } @@ -81,7 +81,7 @@ public class NSClientInternalPlugin implements PluginBase { @Override public String getFragmentClass() { - return NSClientInternalFragment.class.getName(); + return NSClientFragment.class.getName(); } @Override @@ -126,7 +126,7 @@ public class NSClientInternalPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) this.fragmentEnabled = fragmentEnabled; } @@ -177,7 +177,9 @@ public class NSClientInternalPlugin implements PluginBase { handler.post(new Runnable() { @Override public void run() { - listLog = new ArrayList<>(); + synchronized (listLog) { + listLog.clear(); + } MainApp.bus().post(new EventNSClientUpdateGUI()); } }); @@ -187,22 +189,25 @@ public class NSClientInternalPlugin implements PluginBase { handler.post(new Runnable() { @Override public void run() { - listLog.add(ev); - // remove the first line if log is too large - if (listLog.size() >= Constants.MAX_LOG_LINES) { - listLog.remove(0); + synchronized (listLog) { + listLog.add(ev); + // remove the first line if log is too large + if (listLog.size() >= Constants.MAX_LOG_LINES) { + listLog.remove(0); + } } MainApp.bus().post(new EventNSClientUpdateGUI()); } }); } - static synchronized void updateLog() { + synchronized void updateLog() { try { StringBuilder newTextLog = new StringBuilder(); - List temporaryList = new ArrayList<>(listLog); - for (EventNSClientNewLog log : temporaryList) { - newTextLog.append(log.toPreparedHtml()); + synchronized (listLog) { + for (EventNSClientNewLog log : listLog) { + newTextLog.append(log.toPreparedHtml()); + } } textLog = Html.fromHtml(newTextLog.toString()); } catch (OutOfMemoryError e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java index 889128abdc..17cc1dced3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/UploadQueue.java @@ -48,7 +48,7 @@ public class UploadQueue { public void run() { log.debug("QUEUE adding: " + dbr.data); MainApp.getDbHelper().create(dbr); - NSClientInternalPlugin plugin = MainApp.getSpecificPlugin(NSClientInternalPlugin.class); + NSClientPlugin plugin = NSClientPlugin.getPlugin(); if (plugin != null) { plugin.resend("newdata"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java index 6bdf824b7c..a07ae3db39 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/AckAlarmReceiver.java @@ -6,19 +6,13 @@ import android.content.Intent; import android.os.Bundle; import android.os.PowerManager; -import org.json.JSONException; -import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.DbRequest; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; -import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.data.AlarmAck; import info.nightscout.androidaps.plugins.NSClientInternal.services.NSClientService; import info.nightscout.utils.SP; @@ -32,8 +26,8 @@ public class AckAlarmReceiver extends BroadcastReceiver { PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, AckAlarmReceiver.class.getSimpleName()); - NSClientInternalPlugin nsClientInternalPlugin = MainApp.getSpecificPlugin(NSClientInternalPlugin.class); - if (!nsClientInternalPlugin.isEnabled(PluginBase.GENERAL)) { + NSClientPlugin nsClientPlugin = MainApp.getSpecificPlugin(NSClientPlugin.class); + if (!nsClientPlugin.isEnabled(PluginBase.GENERAL)) { return; } if (SP.getBoolean(R.string.key_ns_noupload, false)) { @@ -53,7 +47,7 @@ public class AckAlarmReceiver extends BroadcastReceiver { ack.group = bundles.getString("group"); ack.silenceTime = bundles.getLong("silenceTime"); - NSClientService nsClientService = nsClientInternalPlugin.nsClientService; + NSClientService nsClientService = nsClientPlugin.nsClientService; if (nsClientService != null) nsClientService.sendAlarmAck(ack); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java index c3cea9806a..4ebd36c31a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/receivers/DBAccessReceiver.java @@ -15,7 +15,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.DbRequest; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastTreatment; import info.nightscout.utils.DateUtil; @@ -105,8 +105,8 @@ public class DBAccessReceiver extends BroadcastReceiver { } public boolean shouldUpload() { - NSClientInternalPlugin nsClientInternalPlugin = MainApp.getSpecificPlugin(NSClientInternalPlugin.class); - return nsClientInternalPlugin.isEnabled(PluginBase.GENERAL) && !SP.getBoolean(R.string.key_ns_noupload, false); + NSClientPlugin nsClientPlugin = MainApp.getSpecificPlugin(NSClientPlugin.class); + return nsClientPlugin.isEnabled(PluginBase.GENERAL) && !SP.getBoolean(R.string.key_ns_noupload, false); } public void genereateTreatmentOfflineBroadcast(DbRequest request) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java index 1b1b2884d6..c2c2348610 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java @@ -34,7 +34,7 @@ import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.plugins.NSClientInternal.NSClientInternalPlugin; +import info.nightscout.androidaps.plugins.NSClientInternal.NSClientPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAddAck; import info.nightscout.androidaps.plugins.NSClientInternal.acks.NSAuthAck; @@ -180,7 +180,7 @@ public class NSClientService extends Service { @Subscribe public void onStatusEvent(EventConfigBuilderChange ev) { - if (nsEnabled != MainApp.getSpecificPlugin(NSClientInternalPlugin.class).isEnabled(PluginBase.GENERAL)) { + if (nsEnabled != MainApp.getSpecificPlugin(NSClientPlugin.class).isEnabled(PluginBase.GENERAL)) { latestDateInReceivedData = 0; destroy(); initialize(); @@ -202,7 +202,7 @@ public class NSClientService extends Service { nsAPIhashCode = Hashing.sha1().hashString(nsAPISecret, Charsets.UTF_8).toString(); MainApp.bus().post(new EventNSClientStatus("Initializing")); - if (MainApp.getSpecificPlugin(NSClientInternalPlugin.class).paused) { + if (MainApp.getSpecificPlugin(NSClientPlugin.class).paused) { MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "paused")); MainApp.bus().post(new EventNSClientStatus("Paused")); } else if (!nsEnabled) { @@ -313,7 +313,7 @@ public class NSClientService extends Service { } public void readPreferences() { - nsEnabled = MainApp.getSpecificPlugin(NSClientInternalPlugin.class).isEnabled(PluginBase.GENERAL); + nsEnabled = MainApp.getSpecificPlugin(NSClientPlugin.class).isEnabled(PluginBase.GENERAL); nsURL = SP.getString(R.string.key_nsclientinternal_url, ""); nsAPISecret = SP.getString(R.string.key_nsclientinternal_api_secret, ""); nsDevice = SP.getString("careportal_enteredby", ""); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java index 5fc7809f4e..0c92df635c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java @@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; @@ -205,8 +206,8 @@ public class DetermineBasalAdapterAMAJS { mProfile.put("target_bg", targetBg); mProfile.put("carb_ratio", profile.getIc()); mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); - mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3)); - mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d)); + mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)); + mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d)); mProfile.put("skip_neutral_temps", true); mProfile.put("current_basal", basalrate); mProfile.put("temptargetSet", tempTargetSet); @@ -250,7 +251,7 @@ public class DetermineBasalAdapterAMAJS { mMealData.put("boluses", mealData.boluses); mMealData.put("mealCOB", mealData.mealCOB); - if (MainApp.getConfigBuilder().isAMAModeEnabled()) { + if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) { mAutosensData = new JSONObject(); mAutosensData.put("ratio", autosensDataRatio); } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java index 50dde42674..cb2b4a0091 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalResultAMA.java @@ -22,7 +22,7 @@ public class DetermineBasalResultAMA extends APSResult { json = j; if (result.containsKey("error")) { reason = result.get("error").toString(); - tempBasalReqested = false; + tempBasalRequested = false; rate = -1; duration = -1; } else { @@ -32,17 +32,17 @@ public class DetermineBasalResultAMA extends APSResult { if (result.containsKey("rate")) { rate = (Double) result.get("rate"); if (rate < 0d) rate = 0d; - tempBasalReqested = true; + tempBasalRequested = true; } else { rate = -1; - tempBasalReqested = false; + tempBasalRequested = false; } if (result.containsKey("duration")) { duration = ((Double) result.get("duration")).intValue(); //changeRequested as above } else { duration = -1; - tempBasalReqested = false; + tempBasalRequested = false; } } bolusRequested = false; @@ -58,7 +58,7 @@ public class DetermineBasalResultAMA extends APSResult { newResult.reason = reason; newResult.rate = rate; newResult.duration = duration; - newResult.tempBasalReqested = tempBasalReqested; + newResult.tempBasalRequested = tempBasalRequested; newResult.rate = rate; newResult.duration = duration; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java index dfab195125..4c69a347b4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.Date; import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -17,6 +18,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.interfaces.APSInterface; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; @@ -74,7 +76,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { @Override public boolean isEnabled(int type) { - boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; + boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump() != null && ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; return type == APS && fragmentEnabled && pumpCapable; } @@ -110,7 +112,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == APS) this.fragmentEnabled = fragmentEnabled; } @@ -173,8 +175,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { String units = profile.getUnits(); - double maxIob = SP.getDouble("openapsma_max_iob", 1.5d); - double maxBasal = SP.getDouble("openapsma_max_basal", 1d); + double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); double minBg = Profile.toMgdl(profile.getTargetLow(), units); double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); double targetBg = Profile.toMgdl(profile.getTarget(), units); @@ -191,7 +192,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { MealData mealData = MainApp.getConfigBuilder().getMealData(); Profiler.log(log, "getMealData()", startPart); - maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob); + double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); minBg = HardLimits.verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); maxBg = HardLimits.verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]); @@ -207,9 +208,6 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { } - maxIob = HardLimits.verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA()); - maxBasal = HardLimits.verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); - if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; if (!HardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) @@ -222,7 +220,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { return; startPart = new Date(); - if (MainApp.getConfigBuilder().isAMAModeEnabled()) { + if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) { lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); } else { lastAutosensResult = new AutosensResult(); @@ -246,17 +244,17 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { Profiler.log(log, "AMA calculation", start); // Fix bug determine basal if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress()) - determineBasalResultAMA.tempBasalReqested = false; + determineBasalResultAMA.tempBasalRequested = false; // limit requests on openloop mode - if (!MainApp.getConfigBuilder().isClosedModeEnabled()) { + if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { long now = System.currentTimeMillis(); TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(now); - if (activeTemp != null && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) { + if (activeTemp != null && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) { // going to cancel } else if (activeTemp != null && Math.abs(determineBasalResultAMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) { - determineBasalResultAMA.tempBasalReqested = false; + determineBasalResultAMA.tempBasalRequested = false; } else if (activeTemp == null && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) - determineBasalResultAMA.tempBasalReqested = false; + determineBasalResultAMA.tempBasalRequested = false; } determineBasalResultAMA.iob = iobArray[0]; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java index 3f40c02980..75928f09d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/DetermineBasalResultMA.java @@ -20,7 +20,7 @@ public class DetermineBasalResultMA extends APSResult { json = j; if (result.containsKey("error")) { reason = (String) result.get("error"); - tempBasalReqested = false; + tempBasalRequested = false; rate = -1; duration = -1; mealAssist = ""; @@ -31,17 +31,17 @@ public class DetermineBasalResultMA extends APSResult { if (result.containsKey("rate")) { rate = (Double) result.get("rate"); if (rate < 0d) rate = 0d; - tempBasalReqested = true; + tempBasalRequested = true; } else { rate = -1; - tempBasalReqested = false; + tempBasalRequested = false; } if (result.containsKey("duration")) { duration = ((Double) result.get("duration")).intValue(); //changeRequested as above } else { duration = -1; - tempBasalReqested = false; + tempBasalRequested = false; } if (result.containsKey("mealAssist")) { mealAssist = result.get("mealAssist").toString(); @@ -58,10 +58,10 @@ public class DetermineBasalResultMA extends APSResult { newResult.reason = new String(reason); newResult.rate = rate; newResult.duration = duration; - newResult.tempBasalReqested = isChangeRequested(); + newResult.tempBasalRequested = isChangeRequested(); newResult.rate = rate; newResult.duration = duration; - newResult.tempBasalReqested = isChangeRequested(); + newResult.tempBasalRequested = isChangeRequested(); try { newResult.json = new JSONObject(json.toString()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java index 76df63e752..7fb7a3e207 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.Date; import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -17,6 +18,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.interfaces.APSInterface; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; @@ -29,7 +31,6 @@ import info.nightscout.utils.HardLimits; import info.nightscout.utils.Profiler; import info.nightscout.utils.Round; import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; import static info.nightscout.utils.HardLimits.checkOnlyHardLimits; import static info.nightscout.utils.HardLimits.verifyHardLimits; @@ -75,13 +76,13 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { @Override public boolean isEnabled(int type) { - boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; + boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump() != null && ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; return type == APS && fragmentEnabled && pumpCapable; } @Override public boolean isVisibleInTabs(int type) { - boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; + boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump() != null && ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; return type == APS && fragmentVisible && pumpCapable; } @@ -111,7 +112,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == APS) this.fragmentEnabled = fragmentEnabled; } @@ -174,8 +175,8 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { String units = profile.getUnits(); - double maxIob = SP.getDouble("openapsma_max_iob", 1.5d); - double maxBasal = SafeParse.stringToDouble(SP.getString("openapsma_max_basal", "1")); + double maxBasal = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); + double minBg = Profile.toMgdl(profile.getTargetLow(), units); double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); double targetBg = Profile.toMgdl(profile.getTarget(), units); @@ -193,7 +194,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { MealData mealData = MainApp.getConfigBuilder().getMealData(); - maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob); + double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); Profiler.log(log, "MA data gathering", start); minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); @@ -207,9 +208,6 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { targetBg = verifyHardLimits(tempTarget.target(), "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); } - maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA()); - maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); - if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) @@ -235,16 +233,16 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { DetermineBasalResultMA determineBasalResultMA = determineBasalAdapterMAJS.invoke(); // Fix bug determinef basal if (determineBasalResultMA.rate == 0d && determineBasalResultMA.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress()) - determineBasalResultMA.tempBasalReqested = false; + determineBasalResultMA.tempBasalRequested = false; // limit requests on openloop mode - if (!MainApp.getConfigBuilder().isClosedModeEnabled()) { + if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(now); if (activeTemp != null && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) { // going to cancel } else if (activeTemp != null && Math.abs(determineBasalResultMA.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) { - determineBasalResultMA.tempBasalReqested = false; + determineBasalResultMA.tempBasalRequested = false; } else if (activeTemp == null && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) - determineBasalResultMA.tempBasalReqested = false; + determineBasalResultMA.tempBasalRequested = false; } determineBasalResultMA.iob = iobTotal; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java index 9df54b34d3..12c3122a76 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java @@ -27,12 +27,10 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; -import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback; -import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -48,6 +46,7 @@ public class DetermineBasalAdapterSMBJS { private JSONObject mCurrentTemp; private JSONObject mAutosensData = null; private boolean mMicrobolusAllowed; + private boolean mSMBAlwaysAllowed; private String storedCurrentTemp = null; private String storedIobData = null; @@ -57,6 +56,7 @@ public class DetermineBasalAdapterSMBJS { private String storedMeal_data = null; private String storedAutosens_data = null; private String storedMicroBolusAllowed = null; + private String storedSMBAlwaysAllowed = null; private String scriptDebug = ""; @@ -84,6 +84,7 @@ public class DetermineBasalAdapterSMBJS { log.debug("Autosens data: " + (storedAutosens_data = "undefined")); log.debug("Reservoir data: " + "undefined"); log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed)); + log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed)); DetermineBasalResultSMB determineBasalResultSMB = null; @@ -212,7 +213,8 @@ public class DetermineBasalAdapterSMBJS { MealData mealData, double autosensDataRatio, boolean tempTargetSet, - boolean microBolusAllowed + boolean microBolusAllowed, + boolean smbAlwaysAllowed ) throws JSONException { String units = profile.getUnits(); @@ -229,8 +231,8 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("target_bg", targetBg); mProfile.put("carb_ratio", profile.getIc()); mProfile.put("sens", Profile.toMgdl(profile.getIsf(), units)); - mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3)); - mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d)); + mProfile.put("max_daily_safety_multiplier", SP.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)); + mProfile.put("current_basal_safety_multiplier", SP.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4d)); mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity); mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity); @@ -246,12 +248,11 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap); mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false)); mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable); - boolean SMBEnabled = SP.getBoolean(R.string.key_use_smb, false) && MainApp.getConfigBuilder().isClosedModeEnabled(); - mProfile.put("enableSMB_with_COB", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_with_COB, false)); - mProfile.put("enableSMB_with_temptarget", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_with_temptarget, false)); - mProfile.put("allowSMB_with_high_temptarget", SMBEnabled && SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false)); - mProfile.put("enableSMB_always", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_always, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported()); - mProfile.put("enableSMB_after_carbs", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported()); + mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false)); + mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false)); + mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false)); + mProfile.put("enableSMB_always", SP.getBoolean(R.string.key_enableSMB_always, false) && smbAlwaysAllowed); + mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && smbAlwaysAllowed); mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes)); mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold); @@ -302,7 +303,7 @@ public class DetermineBasalAdapterSMBJS { mMealData.put("lastCarbTime", mealData.lastCarbTime); - if (MainApp.getConfigBuilder().isAMAModeEnabled()) { + if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) { mAutosensData = new JSONObject(); mAutosensData.put("ratio", autosensDataRatio); } else { @@ -310,6 +311,7 @@ public class DetermineBasalAdapterSMBJS { mAutosensData.put("ratio", 1.0); } mMicrobolusAllowed = microBolusAllowed; + mSMBAlwaysAllowed = smbAlwaysAllowed; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java index 0320b3633d..59c1dd95e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalResultSMB.java @@ -35,7 +35,7 @@ public class DetermineBasalResultSMB extends APSResult { if (result.has("carbsReq")) carbsReq = result.getDouble("carbsReq"); if (result.has("rate") && result.has("duration")) { - tempBasalReqested = true; + tempBasalRequested = true; rate = result.getDouble("rate"); if (rate < 0d) rate = 0d; duration = result.getInt("duration"); @@ -74,7 +74,7 @@ public class DetermineBasalResultSMB extends APSResult { newResult.reason = reason; newResult.rate = rate; newResult.duration = duration; - newResult.tempBasalReqested = tempBasalReqested; + newResult.tempBasalRequested = tempBasalRequested; newResult.bolusRequested = bolusRequested; newResult.rate = rate; newResult.duration = duration; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java index 6c720adc48..dcba600fb4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java @@ -16,6 +16,9 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; @@ -24,19 +27,32 @@ import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateRes import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; -public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnClickListener { +public class OpenAPSSMBFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(OpenAPSSMBFragment.class); + @BindView(R.id.openapsma_run) Button run; + @BindView(R.id.openapsma_lastrun) TextView lastRunView; + @BindView(R.id.openapsma_constraints) + TextView constraintsView; + @BindView(R.id.openapsma_glucosestatus) TextView glucoseStatusView; + @BindView(R.id.openapsma_currenttemp) TextView currentTempView; + @BindView(R.id.openapsma_iobdata) TextView iobDataView; + @BindView(R.id.openapsma_profile) TextView profileView; + @BindView(R.id.openapsma_mealdata) TextView mealDataView; + @BindView(R.id.openapsma_autosensdata) TextView autosensDataView; + @BindView(R.id.openapsma_result) TextView resultView; + @BindView(R.id.openapsma_scriptdebugdata) TextView scriptdebugView; + @BindView(R.id.openapsma_request) TextView requestView; @Override @@ -44,32 +60,14 @@ public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnCli Bundle savedInstanceState) { View view = inflater.inflate(R.layout.openapsama_fragment, container, false); - run = (Button) view.findViewById(R.id.openapsma_run); - run.setOnClickListener(this); - lastRunView = (TextView) view.findViewById(R.id.openapsma_lastrun); - glucoseStatusView = (TextView) view.findViewById(R.id.openapsma_glucosestatus); - currentTempView = (TextView) view.findViewById(R.id.openapsma_currenttemp); - iobDataView = (TextView) view.findViewById(R.id.openapsma_iobdata); - profileView = (TextView) view.findViewById(R.id.openapsma_profile); - mealDataView = (TextView) view.findViewById(R.id.openapsma_mealdata); - autosensDataView = (TextView) view.findViewById(R.id.openapsma_autosensdata); - scriptdebugView = (TextView) view.findViewById(R.id.openapsma_scriptdebugdata); - resultView = (TextView) view.findViewById(R.id.openapsma_result); - requestView = (TextView) view.findViewById(R.id.openapsma_request); - - updateGUI(); + unbinder = ButterKnife.bind(this, view); return view; } - @Override - public void onClick(View view) { - switch (view.getId()) { - case R.id.openapsma_run: - OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button"); - FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run")); - break; - } - + @OnClick(R.id.openapsma_run) + public void onRunClick() { + OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button"); + FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run")); } @Subscribe @@ -109,6 +107,8 @@ public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnCli profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam())); mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam())); scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug()); + if (lastAPSResult != null && lastAPSResult.inputConstraints != null) + constraintsView.setText(lastAPSResult.inputConstraints.getReasons()); } if (plugin.lastAPSRun != null) { lastRunView.setText(plugin.lastAPSRun.toLocaleString()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java index f10e6cb0be..2f50d72335 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.Date; import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -17,6 +18,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.interfaces.APSInterface; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; @@ -79,7 +81,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { @Override public boolean isEnabled(int type) { - boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; + boolean pumpCapable = ConfigBuilderPlugin.getActivePump() == null || ConfigBuilderPlugin.getActivePump() != null && ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable; return type == APS && fragmentEnabled && pumpCapable; } @@ -115,7 +117,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == APS) this.fragmentEnabled = fragmentEnabled; } @@ -178,8 +180,11 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { String units = profile.getUnits(); - double maxIob = SP.getDouble("openapsma_max_iob", 1.5d); - double maxBasal = SP.getDouble("openapsma_max_basal", 1d); + Constraint inputConstraints = new Constraint<>(0d); // fake. only for collecting all results + + Constraint maxBasalConstraint = MainApp.getConstraintChecker().getMaxBasalAllowed(profile); + inputConstraints.copyReasons(maxBasalConstraint); + double maxBasal = maxBasalConstraint.value(); double minBg = Profile.toMgdl(profile.getTargetLow(), units); double maxBg = Profile.toMgdl(profile.getTargetHigh(), units); double targetBg = Profile.toMgdl(profile.getTarget(), units); @@ -196,7 +201,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { MealData mealData = MainApp.getConfigBuilder().getMealData(); Profiler.log(log, "getMealData()", startPart); - maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob); + double maxIob = MainApp.getConstraintChecker().getMaxIOBAllowed().value(); minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]); @@ -212,9 +217,6 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { } - maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobSMB()); - maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); - if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; if (!checkOnlyHardLimits(profile.getIcTimeFromMidnight(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; @@ -224,11 +226,20 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; startPart = new Date(); - if (MainApp.getConfigBuilder().isAMAModeEnabled()) { + if (MainApp.getConstraintChecker().isAutosensModeEnabled().value()) { lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); } else { lastAutosensResult = new AutosensResult(); } + + Constraint smbAllowed = new Constraint<>(true); + MainApp.getConstraintChecker().isSMBModeEnabled(smbAllowed); + inputConstraints.copyReasons(smbAllowed); + + Constraint smbAlwaysEnabled = new Constraint<>(true); + MainApp.getConstraintChecker().isAdvancedFilteringEnabled(smbAlwaysEnabled); + inputConstraints.copyReasons(smbAlwaysEnabled); + Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); Profiler.log(log, "SMB data gathering", start); @@ -237,7 +248,8 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData, lastAutosensResult.ratio, //autosensDataRatio isTempTarget, - true //microBolusAllowed + smbAllowed.value(), + smbAlwaysEnabled.value() ); } catch (JSONException e) { log.error(e.getMessage()); @@ -251,16 +263,16 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { // TODO still needed with oref1? // Fix bug determine basal if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !MainApp.getConfigBuilder().isTempBasalInProgress()) - determineBasalResultSMB.tempBasalReqested = false; + determineBasalResultSMB.tempBasalRequested = false; // limit requests on openloop mode - if (!MainApp.getConfigBuilder().isClosedModeEnabled()) { + if (!MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(now); if (activeTemp != null && determineBasalResultSMB.rate == 0 && determineBasalResultSMB.duration == 0) { // going to cancel } else if (activeTemp != null && Math.abs(determineBasalResultSMB.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < 0.1) { - determineBasalResultSMB.tempBasalReqested = false; + determineBasalResultSMB.tempBasalRequested = false; } else if (activeTemp == null && Math.abs(determineBasalResultSMB.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) - determineBasalResultSMB.tempBasalReqested = false; + determineBasalResultSMB.tempBasalRequested = false; } determineBasalResultSMB.iob = iobArray[0]; @@ -271,6 +283,8 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { log.error("Unhandled exception", e); } + determineBasalResultSMB.inputConstraints = inputConstraints; + lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS; lastAPSResult = determineBasalResultSMB; lastAPSRun = new Date(now); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java index 3c068b79d7..a17470eb2c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java @@ -43,6 +43,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DateUtil; @@ -120,7 +121,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); + maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); editCarbs = view.findViewById(R.id.newcarb_carbsamount); @@ -303,7 +304,7 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D okClicked = true; try { final Integer carbs = SafeParse.stringToInt(editCarbs.getText()); - Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs); + Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value(); List actions = new LinkedList<>(); if (carbs > 0) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java index f72e1c1e87..b6059f85be 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java @@ -44,9 +44,11 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -119,11 +121,11 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount); - editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher); + editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate); timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime); @@ -159,7 +161,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, } private String toSignedString(double value) { - return value > 0 ? "+" + value : String.valueOf(value); + String formatted = DecimalFormatter.toPumpSupportedBolus(value); + return value > 0 ? "+" + formatted : formatted; } @Override @@ -223,7 +226,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, try { Double insulin = SafeParse.stringToDouble(editInsulin.getText()); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); List actions = new LinkedList<>(); if (insulin > 0) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java index d17dfdd0b8..72776b58e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java @@ -31,6 +31,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.FabricPrivacy; @@ -95,8 +96,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); - maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); + maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); editCarbs = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_carbsamount); editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); @@ -128,8 +129,8 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene String confirmMessage = MainApp.gs(R.string.entertreatmentquestion) + "
"; - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin); - Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value(); if (insulin > 0) { confirmMessage += MainApp.gs(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java index 0d59983796..d48b2ccf34 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java @@ -52,16 +52,17 @@ import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventRefreshOverview; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.queue.Callback; -import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -142,16 +143,14 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com @Subscribe public void onStatusEvent(final EventNewBG e) { - if (e.isFromActiveBgSource && e.isNew && e.isCurrent()) { - Activity activity = getActivity(); - if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - calculateInsulin(); - } - }); - } + Activity activity = getActivity(); + if (activity != null) + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + calculateInsulin(); + } + }); } @Subscribe @@ -238,13 +237,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com superbolusCheckbox.setVisibility(SP.getBoolean(R.string.key_usesuperbolus, false) ? View.VISIBLE : View.GONE); - Integer maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); - Double maxCorrection = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + Integer maxCarbs = MainApp.getConstraintChecker().getMaxCarbsAllowed().value(); + Double maxCorrection = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher); double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; - editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, new DecimalFormat("0.00"), false, textWatcher); + editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false); initDialog(); @@ -261,19 +260,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } private void saveCheckedStates() { - //SP.putBoolean(getString(R.string.key_wizard_include_bg), bgCheckbox.isChecked()); SP.putBoolean(getString(R.string.key_wizard_include_cob), cobCheckbox.isChecked()); SP.putBoolean(getString(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked()); - //SP.putBoolean(getString(R.string.key_wizard_include_bolus_iob), bolusIobCheckbox.isChecked()); - //SP.putBoolean(getString(R.string.key_wizard_include_basal_iob), basalIobCheckbox.isChecked()); } private void loadCheckedStates() { - //bgCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bg), true)); bgtrendCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_trend_bg), false)); cobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_cob), false)); - //bolusIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bolus_iob), true)); - //basalIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_basal_iob), true)); } @Override @@ -298,13 +291,15 @@ 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); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(calculatedTotalInsulin); - Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(calculatedCarbs); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(calculatedTotalInsulin)).value(); + Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(calculatedCarbs)).value(); confirmMessage += "
" + getString(R.string.bolus) + ": " + "" + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U" + ""; confirmMessage += "
" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g"; @@ -343,7 +338,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) { @@ -460,13 +455,15 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com Double c_bg = SafeParse.stringToDouble(editBg.getText()); Integer c_carbs = SafeParse.stringToInt(editCarbs.getText()); Double c_correction = SafeParse.stringToDouble(editCorr.getText()); - Double corrAfterConstraint = MainApp.getConfigBuilder().applyBolusConstraints(c_correction); + Double corrAfterConstraint = c_correction; + if (c_correction > 0) + c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value(); if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work editCorr.setValue(0d); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied)); return; } - Integer carbsAfterConstraint = MainApp.getConfigBuilder().applyCarbsConstraints(c_carbs); + Integer carbsAfterConstraint = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(c_carbs)).value(); if (c_carbs - carbsAfterConstraint != 0) { editCarbs.setValue(0d); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied)); @@ -533,7 +530,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) { - String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.to2Decimal(calculatedTotalInsulin) + "U") : ""; + String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.toPumpSupportedBolus(calculatedTotalInsulin) + "U") : ""; String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : ""; total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText); okButton.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index e90a77c524..87927cabf4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -87,6 +87,7 @@ import info.nightscout.androidaps.events.EventTreatmentChange; 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.Careportal.CareportalFragment; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; @@ -287,13 +288,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, llm = new LinearLayoutManager(view.getContext()); notificationsView.setLayoutManager(llm); + float scaledDensity = getResources().getDisplayMetrics().scaledDensity; + int axisWidth = (int) Math.round(scaledDensity * scaledDensity * scaledDensity * 6); + bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); bgGraph.getGridLabelRenderer().reloadStyles(); iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); iobGraph.getGridLabelRenderer().reloadStyles(); iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); - bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50); - iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50); + bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); + iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6); @@ -439,7 +443,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)) { @@ -473,9 +477,12 @@ 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); + activeloop.setPluginEnabled(PluginBase.LOOP, false); activeloop.setFragmentVisible(PluginBase.LOOP, false); MainApp.getConfigBuilder().storeSettings(); updateGUI("suspendmenu"); @@ -490,7 +497,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) { - activeloop.setFragmentEnabled(PluginBase.LOOP, true); + activeloop.setPluginEnabled(PluginBase.LOOP, true); activeloop.setFragmentVisible(PluginBase.LOOP, true); MainApp.getConfigBuilder().storeSettings(); updateGUI("suspendmenu"); @@ -526,23 +533,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))) { @@ -723,8 +730,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00"); String confirmMessage = getString(R.string.entertreatmentquestion); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(wizard.calculatedTotalInsulin); - Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(quickWizardEntry.carbs()); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(wizard.calculatedTotalInsulin)).value(); + Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(quickWizardEntry.carbs())).value(); confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U"; confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g"; @@ -760,7 +767,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) { @@ -1016,6 +1023,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } + Constraint closedLoopEnabled = MainApp.getConstraintChecker().isClosedLoopAllowed(); + // open loop mode final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; if (Config.APS && pump.getPumpDescription().isTempBasalCapable) { @@ -1036,7 +1045,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended)); apsModeView.setTextColor(Color.WHITE); } else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) { - if (MainApp.getConfigBuilder().isClosedModeEnabled()) { + if (closedLoopEnabled.value()) { apsModeView.setText(MainApp.sResources.getString(R.string.closedloop)); } else { apsModeView.setText(MainApp.sResources.getString(R.string.openloop)); @@ -1066,7 +1075,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // **** Temp button **** if (acceptTempLayout != null) { - boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed + boolean showAcceptButton = !closedLoopEnabled.value(); // Open mode needed showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.isChangeRequested(); // change is requested @@ -1160,7 +1169,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, extendedBolusView.setText(extendedBolusText); } if (extendedBolusText.equals("")) - extendedBolusView.setVisibility(View.GONE); + extendedBolusView.setVisibility(View.INVISIBLE); else extendedBolusView.setVisibility(View.VISIBLE); } @@ -1188,7 +1197,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, quickWizardButton.setVisibility(View.VISIBLE); String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g"; BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false); - text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U"; + text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U"; quickWizardButton.setText(text); if (wizard.calculatedTotalInsulin <= 0) quickWizardButton.setVisibility(View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java index 8b276f937d..376ee9ca87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java @@ -96,7 +96,7 @@ public class OverviewPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { // Always enabled } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java index 07c6e8bf96..47e256f42d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java @@ -245,6 +245,7 @@ public class GraphData { value = (profile.getTargetLow(time) + profile.getTargetHigh(time)) / 2; } else { value = tt.target(); + value = Profile.fromMgdlToUnits(value, profile.getUnits()); } if (lastTarget > 0 && lastTarget != value) { targetsSeriesArray.add(new DataPoint(time, lastTarget)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java index 0051518bb4..9c8e312fb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -48,11 +48,11 @@ import java.util.Iterator; */ public class PointsWithLabelGraphSeries extends BaseSeries { // Default spSize - int spSize = 12; + int spSize = 14; // Convert the sp to pixels Context context = MainApp.instance().getApplicationContext(); float scaledTextSize = spSize * context.getResources().getDisplayMetrics().scaledDensity; - float scaledPxSize = context.getResources().getDisplayMetrics().scaledDensity * 1.5f; + float scaledPxSize = context.getResources().getDisplayMetrics().scaledDensity * 3f; /** * choose a predefined shape to render for @@ -233,9 +233,10 @@ public class PointsWithLabelGraphSeries e } else if (value.getShape() == Shape.SMB) { mPaint.setStrokeWidth(2); Point[] points = new Point[3]; - points[0] = new Point((int)endX, (int)(endY-value.getSize())); - points[1] = new Point((int)(endX+value.getSize()), (int)(endY+value.getSize()*0.67)); - points[2] = new Point((int)(endX-value.getSize()), (int)(endY+value.getSize()*0.67)); + float size = value.getSize() * scaledPxSize; + points[0] = new Point((int)endX, (int)(endY-size)); + points[1] = new Point((int)(endX+size), (int)(endY+size*0.67)); + points[2] = new Point((int)(endX-size), (int)(endY+size*0.67)); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); drawArrows(points, canvas, mPaint); } else if (value.getShape() == Shape.EXTENDEDBOLUS) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java index a68864b9c8..282b3e16a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java @@ -94,7 +94,7 @@ public class PersistentNotificationPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (getType() == type) { this.fragmentEnabled = fragmentEnabled; enableDisableNotification(fragmentEnabled); @@ -255,8 +255,7 @@ public class PersistentNotificationPlugin implements PluginBase { @Subscribe public void onStatusEvent(final EventNewBG ev) { - if (ev.isFromActiveBgSource && ev.isNew && ev.isCurrent()) - updateNotification(); + updateNotification(); } @Subscribe diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java index 69272cc2ae..c59537ad6b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfilePlugin.java @@ -107,7 +107,7 @@ public class LocalProfilePlugin implements PluginBase, ProfileInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PROFILE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java index c2d7cfabfc..a50e47b998 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfilePlugin.java @@ -96,7 +96,7 @@ public class NSProfilePlugin implements PluginBase, ProfileInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PROFILE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java index b538a28512..92f810c3a0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfilePlugin.java @@ -102,7 +102,7 @@ public class SimpleProfilePlugin implements PluginBase, ProfileInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PROFILE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java index d7c0a4b7c6..9753f35ea4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java @@ -233,7 +233,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis // reservoir int reservoirLevel = plugin.getPump().reservoirLevel; if (reservoirLevel != -1) { - reservoirView.setText(reservoirLevel + " " + MainApp.sResources.getString(R.string.treatments_wizard_unit_label)); + reservoirView.setText(reservoirLevel + " " + MainApp.sResources.getString(R.string.insulin_unit_shortname)); } else if (ps.insulinState == PumpState.LOW) { reservoirView.setText(MainApp.gs(R.string.combo_reservoir_low)); } else if (ps.insulinState == PumpState.EMPTY) { @@ -275,7 +275,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis if (bolus != null) { long agoMsc = System.currentTimeMillis() - bolus.timestamp; double bolusMinAgo = agoMsc / 60d / 1000d; - String unit = MainApp.gs(R.string.treatments_wizard_unit_label); + String unit = MainApp.gs(R.string.insulin_unit_shortname); String ago; if ((agoMsc < 60 * 1000)) { ago = MainApp.gs(R.string.combo_pump_connected_now); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index 65ff6f4a47..33f6dc8b0a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -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; @@ -36,6 +35,7 @@ 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.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; @@ -225,7 +225,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PUMP) this.fragmentEnabled = fragmentEnabled; } @@ -428,7 +428,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return; } pump.basalProfile = readBasalResult.basalProfile; - validBasalRateProfileSelectedOnPump = true; + setValidBasalRateProfileSelectedOnPump(true); pump.initialized = true; MainApp.bus().post(new EventInitializationChanged()); @@ -750,7 +750,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf * the new value (and thus still has the old duration of e.g. 1 min) expires?) */ @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean force) { log.debug("setTempBasalAbsolute called with a rate of " + absoluteRate + " for " + durationInMinutes + " min."); int unroundedPercentage = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue(); int roundedPercentage = (int) (Math.round(absoluteRate / getBaseBasalRate() * 10) * 10); @@ -768,7 +768,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); } @@ -929,7 +929,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (commandResult.success) { pump.lastSuccessfulCmdTime = System.currentTimeMillis(); if (validBasalRateProfileSelectedOnPump && commandResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) { - validBasalRateProfileSelectedOnPump = false; + setValidBasalRateProfileSelectedOnPump(false); Notification n = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_force_disabled_notification), Notification.URGENT); @@ -949,6 +949,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return commandResult; } + public void setValidBasalRateProfileSelectedOnPump(boolean value) { + validBasalRateProfileSelectedOnPump = value; + } + /** * Returns the command result of running ReadPumpState if it wasn't successful, indicating * an error condition. Returns null otherwise. @@ -1457,52 +1461,16 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf private boolean validBasalRateProfileSelectedOnPump = true; @Override - public boolean isLoopEnabled() { - return validBasalRateProfileSelectedOnPump; + public Constraint isLoopInvokationAllowed(Constraint value) { + if (!validBasalRateProfileSelectedOnPump) + value.set(false, MainApp.gs(R.string.novalidbasalrate), this); + return value; } @Override - public boolean isClosedModeEnabled() { - return true; - } - - @Override - public boolean isAutosensModeEnabled() { - return true; - } - - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @Override - public Double applyBasalConstraints(Double absoluteRate) { - return absoluteRate; - } - - @Override - public Integer applyBasalConstraints(Integer percentRate) { - return percentRate; - } - - @Override - public Double applyBolusConstraints(Double insulin) { - return insulin; - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return lowSuspendOnlyLoopEnforcedUntil < System.currentTimeMillis() ? maxIob : 0; + public Constraint applyMaxIOBConstraints(Constraint maxIob) { + if (lowSuspendOnlyLoopEnforcedUntil > System.currentTimeMillis()) + maxIob.setIfSmaller(0d, String.format(MainApp.gs(R.string.limitingmaxiob), 0d, MainApp.gs(R.string.unsafeusage)), this); + return maxIob; } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java index c277fcb8cb..910a7a8b28 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java @@ -7,11 +7,9 @@ import org.json.JSONObject; import org.slf4j.Logger; import java.util.Date; -import java.util.Objects; import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; @@ -19,18 +17,17 @@ 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.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; 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.ProfileNS.NSProfilePlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.comm.RecordTypes; import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecutionService; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; @@ -108,16 +105,16 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PluginBase.PROFILE) mPluginProfileEnabled = fragmentEnabled; else if (type == PluginBase.PUMP) mPluginPumpEnabled = fragmentEnabled; // if pump profile was enabled need to switch to another too if (type == PluginBase.PUMP && !fragmentEnabled && mPluginProfileEnabled) { - setFragmentEnabled(PluginBase.PROFILE, false); + setPluginEnabled(PluginBase.PROFILE, false); setFragmentVisible(PluginBase.PROFILE, false); - NSProfilePlugin.getPlugin().setFragmentEnabled(PluginBase.PROFILE, true); + NSProfilePlugin.getPlugin().setPluginEnabled(PluginBase.PROFILE, true); NSProfilePlugin.getPlugin().setFragmentVisible(PluginBase.PROFILE, true); } } @@ -215,10 +212,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(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - percent = configBuilderPlugin.applyBasalConstraints(percent); + percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value(); if (percent < 0) { result.isTempCancel = false; result.enacted = false; @@ -230,7 +226,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, if (percent > getPumpDescription().maxTempPercent) percent = getPumpDescription().maxTempPercent; long now = System.currentTimeMillis(); - TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(now); + TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(now); if (runningTB != null && runningTB.percentRate == percent && !enforceNew) { result.enacted = false; result.success = true; @@ -266,8 +262,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, @Override public PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - insulin = configBuilderPlugin.applyBolusConstraints(insulin); + insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); @@ -294,7 +289,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"); @@ -437,85 +433,27 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, */ @Override - public PumpEnactResult loadTDDs() { - return loadHistory(RecordTypes.RECORD_TYPE_DAILY); - } - - @Override - public boolean isLoopEnabled() { - return true; - } - - @Override - public boolean isClosedModeEnabled() { - return true; - } - - @Override - public boolean isAutosensModeEnabled() { - return true; - } - - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @SuppressWarnings("PointlessBooleanExpression") - @Override - public Double applyBasalConstraints(Double absoluteRate) { - double origAbsoluteRate = absoluteRate; - if (pump != null) { - if (absoluteRate > pump.maxBasal) { - absoluteRate = pump.maxBasal; - if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h"); - } - } + public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { + if (pump != null) + absoluteRate.setIfSmaller(pump.maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), pump.maxBasal, MainApp.gs(R.string.pumplimit)), this); return absoluteRate; } - @SuppressWarnings("PointlessBooleanExpression") @Override - public Integer applyBasalConstraints(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 applyBasalPercentConstraints(Constraint percentRate, Profile profile) { + percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this); + percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); + return percentRate; } - @SuppressWarnings("PointlessBooleanExpression") @Override - public Double applyBolusConstraints(Double insulin) { - double origInsulin = insulin; - if (pump != null) { - if (insulin > pump.maxBolus) { - insulin = pump.maxBolus; - if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit) - log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U"); - } - } + public Constraint applyBolusConstraints(Constraint insulin) { + if (pump != null) + insulin.setIfSmaller(pump.maxBolus, String.format(MainApp.gs(R.string.limitingbolus), pump.maxBolus, MainApp.gs(R.string.pumplimit)), this); return insulin; } - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return maxIob; - } - @Nullable @Override public ProfileStore getProfile() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java index 7be12e0cb5..ce1a5c392c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java @@ -14,14 +14,15 @@ import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; 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.events.EventPreferenceChange; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService; import info.nightscout.utils.Round; import info.nightscout.utils.SP; @@ -131,8 +132,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); + detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); t.isSMB = detailedBolusInfo.isSMB; @@ -162,7 +162,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { // This is called from APS @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { // Recheck pump status if older than 30 min //This should not be needed while using queue because connection should be done before calling this //if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { @@ -171,8 +171,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { PumpEnactResult result = new PumpEnactResult(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - absoluteRate = configBuilderPlugin.applyBasalConstraints(absoluteRate); + absoluteRate = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); final boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d; final boolean doLowTemp = absoluteRate < getBaseBasalRate(); @@ -250,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 @@ -269,7 +268,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { Integer durationInHalfHours = Math.max(durationInMinutes / 30, 1); // We keep current basal running so need to sub current basal Double extendedRateToSet = absoluteRate - getBaseBasalRate(); - extendedRateToSet = configBuilderPlugin.applyBasalConstraints(extendedRateToSet); + extendedRateToSet = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value(); // needs to be rounded to 0.1 extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2); // *2 because of halfhours diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java index 0e6a3e814a..9173794199 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStart.java @@ -3,9 +3,9 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.utils.HardLimits; public class MsgBolusStart extends MessageBase { @@ -19,9 +19,7 @@ public class MsgBolusStart extends MessageBase { this(); // HARDCODED LIMIT - amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); - if (amount < 0) amount = 0d; - if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus(); + amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); AddParamInt((int) (amount * 100)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java index b04d501ef0..3a33e9f866 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgBolusStartWithSpeed.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.utils.HardLimits; public class MsgBolusStartWithSpeed extends MessageBase { @@ -18,9 +19,7 @@ public class MsgBolusStartWithSpeed extends MessageBase { this(); // HARDCODED LIMIT - amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); - if (amount < 0) amount = 0d; - if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus(); + amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); AddParamInt((int) (amount * 100)); AddParamByte((byte) speed); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java index ee0a9c8aaf..93f66aa200 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgInitConnStatusTime.java @@ -31,17 +31,17 @@ public class MsgInitConnStatusTime extends MessageBase { MainApp.bus().post(new EventNewNotification(notification)); MainApp.getSpecificPlugin(DanaRPlugin.class).disconnect("Wrong Model"); log.debug("Wrong model selected. Switching to Korean DanaR"); - MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentEnabled(PluginBase.PUMP, true); + MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setPluginEnabled(PluginBase.PUMP, true); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, true); - MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, false); + MainApp.getSpecificPlugin(DanaRPlugin.class).setPluginEnabled(PluginBase.PUMP, false); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, false); DanaRPump.reset(); // mark not initialized //If profile coming from pump, switch it as well if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){ - (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false); - (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, true); + (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginBase.PROFILE, false); + (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setPluginEnabled(PluginBase.PROFILE, true); } MainApp.getConfigBuilder().storeSettings(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java index 484078825e..420f0ccbf9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgSetExtendedBolusStart.java @@ -3,9 +3,9 @@ package info.nightscout.androidaps.plugins.PumpDanaR.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.utils.HardLimits; public class MsgSetExtendedBolusStart extends MessageBase { @@ -21,9 +21,7 @@ public class MsgSetExtendedBolusStart extends MessageBase { // HARDCODED LIMITS if (halfhours < 1) halfhours = 1; if (halfhours > 16) halfhours = 16; - amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); - if (amount < 0d) amount = 0d; - if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus(); + amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); AddParamInt((int) (amount * 100)); AddParamByte(halfhours); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java index 0a35d56a17..6462afbe79 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java @@ -14,14 +14,15 @@ import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; 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.events.EventPreferenceChange; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; import info.nightscout.utils.Round; @@ -132,8 +133,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); + detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); t.isSMB = detailedBolusInfo.isSMB; @@ -163,7 +163,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { // This is called from APS @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { // Recheck pump status if older than 30 min //This should not be needed while using queue because connection should be done before calling this //if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { @@ -172,8 +172,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { PumpEnactResult result = new PumpEnactResult(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - absoluteRate = configBuilderPlugin.applyBasalConstraints(absoluteRate); + absoluteRate = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); final boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d; final boolean doLowTemp = absoluteRate < getBaseBasalRate(); @@ -251,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 @@ -270,7 +269,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { Integer durationInHalfHours = Math.max(durationInMinutes / 30, 1); // We keep current basal running so need to sub current basal Double extendedRateToSet = absoluteRate - getBaseBasalRate(); - extendedRateToSet = configBuilderPlugin.applyBasalConstraints(extendedRateToSet); + extendedRateToSet = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value(); // needs to be rounded to 0.1 extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2); // *2 because of halfhours diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java index 89ccb7ae60..6e2b66d2d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/comm/MsgInitConnStatusTime_k.java @@ -33,17 +33,17 @@ public class MsgInitConnStatusTime_k extends MessageBase { MainApp.bus().post(new EventNewNotification(notification)); DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model"); log.debug("Wrong model selected. Switching to export DanaR"); - MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentEnabled(PluginBase.PUMP, false); + MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setPluginEnabled(PluginBase.PUMP, false); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, false); - MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, true); + MainApp.getSpecificPlugin(DanaRPlugin.class).setPluginEnabled(PluginBase.PUMP, true); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, true); DanaRPump.reset(); // mark not initialized //If profile coming from pump, switch it as well if (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).isEnabled(PluginBase.PROFILE)) { - (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false); - (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, true); + (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setPluginEnabled(PluginBase.PROFILE, false); + (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginBase.PROFILE, true); } MainApp.getConfigBuilder().storeSettings(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java index d6d2d44aac..238a5777c2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java @@ -15,11 +15,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import java.util.Objects; import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -30,17 +28,17 @@ 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.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.DanaRInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; 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.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRFragment; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPump; @@ -116,16 +114,16 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PluginBase.PROFILE) this.fragmentProfileEnabled = fragmentEnabled; else if (type == PluginBase.PUMP) this.fragmentPumpEnabled = fragmentEnabled; // if pump profile was enabled need to switch to another too if (type == PluginBase.PUMP && !fragmentEnabled && this.fragmentProfileEnabled) { - setFragmentEnabled(PluginBase.PROFILE, false); + setPluginEnabled(PluginBase.PROFILE, false); setFragmentVisible(PluginBase.PROFILE, false); - MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentEnabled(PluginBase.PROFILE, true); + MainApp.getSpecificPlugin(NSProfilePlugin.class).setPluginEnabled(PluginBase.PROFILE, true); MainApp.getSpecificPlugin(NSProfilePlugin.class).setFragmentVisible(PluginBase.PROFILE, true); } } @@ -275,77 +273,28 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, // Constraints interface @Override - public boolean isLoopEnabled() { - return true; - } - - @Override - public boolean isClosedModeEnabled() { - return true; - } - - @Override - public boolean isAutosensModeEnabled() { - return true; - } - - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @Override - public Double applyBasalConstraints(Double absoluteRate) { - double origAbsoluteRate = absoluteRate; - if (pump != null) { - if (absoluteRate > pump.maxBasal) { - absoluteRate = pump.maxBasal; - if (Config.logConstraintsChanges && origAbsoluteRate != Constants.basalAbsoluteOnlyForCheckLimit) - log.debug("Limiting rate " + origAbsoluteRate + "U/h by pump constraint to " + absoluteRate + "U/h"); - } - } + public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { + if (pump != null) + absoluteRate.setIfSmaller(pump.maxBasal, String.format(MainApp.gs(R.string.limitingbasalratio), pump.maxBasal, MainApp.gs(R.string.pumplimit)), this); return absoluteRate; } @Override - public Integer applyBasalConstraints(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 applyBasalPercentConstraints(Constraint percentRate, Profile profile) { + percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this); + percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); + return percentRate; } + @Override - public Double applyBolusConstraints(Double insulin) { - double origInsulin = insulin; - if (pump != null) { - if (insulin > pump.maxBolus) { - insulin = pump.maxBolus; - if (Config.logConstraintsChanges && origInsulin != Constants.bolusOnlyForCheckLimit) - log.debug("Limiting bolus " + origInsulin + "U by pump constraint to " + insulin + "U"); - } - } + public Constraint applyBolusConstraints(Constraint insulin) { + if (pump != null) + insulin.setIfSmaller(pump.maxBolus, String.format(MainApp.gs(R.string.limitingbolus), pump.maxBolus, MainApp.gs(R.string.pumplimit)), this); return insulin; } - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return maxIob; - } - // Profile interface @Nullable @@ -451,8 +400,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public synchronized PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); + detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { int preferencesSpeed = SP.getInt(R.string.key_danars_bolusspeed, 0); int speed = 12; @@ -514,7 +462,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, // This is called from APS @Override - public synchronized PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public synchronized PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { // Recheck pump status if older than 30 min //This should not be needed while using queue because connection should be done before calling this @@ -524,8 +472,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, PumpEnactResult result = new PumpEnactResult(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - absoluteRate = configBuilderPlugin.applyBasalConstraints(absoluteRate); + absoluteRate = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); final boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d; final boolean doLowTemp = absoluteRate < getBaseBasalRate(); @@ -595,10 +542,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(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - percent = configBuilderPlugin.applyBasalConstraints(percent); + percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value(); if (percent < 0) { result.isTempCancel = false; result.enacted = false; @@ -673,8 +619,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public synchronized PumpEnactResult setExtendedBolus(Double insulin, Integer durationInMinutes) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - insulin = configBuilderPlugin.applyBolusConstraints(insulin); + insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); insulin = Round.roundTo(insulin, getPumpDescription().extendedBolusStep); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java index 4c5cc23ef3..12f2fa95c6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_Bolus_Set_Step_Bolus_Start.java @@ -1,11 +1,13 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import com.cozmo.danar.util.BleCommandUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; -import com.cozmo.danar.util.BleCommandUtil; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.utils.HardLimits; public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet { @@ -26,9 +28,7 @@ public class DanaRS_Packet_Bolus_Set_Step_Bolus_Start extends DanaRS_Packet { this(); // HARDCODED LIMIT - amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); - if (amount < 0) amount = 0d; - if (amount > HardLimits.maxBolus()) amount = HardLimits.maxBolus(); + amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); this.amount = amount; this.speed = speed; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java index c1a6bb54da..3f372de5db 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java @@ -14,12 +14,13 @@ import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.PumpDanaR.AbstractDanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; @@ -121,8 +122,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { // Pump interface @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); + detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { // v2 stores end time for bolus, we need to adjust time // default delivery speed is 12 sec/U @@ -185,7 +185,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { // This is called from APS @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { // Recheck pump status if older than 30 min //This should not be needed while using queue because connection should be done before calling this //if (pump.lastConnection.getTime() + 30 * 60 * 1000L < System.currentTimeMillis()) { @@ -194,8 +194,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { PumpEnactResult result = new PumpEnactResult(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - absoluteRate = configBuilderPlugin.applyBasalConstraints(absoluteRate); + absoluteRate = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); final boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d; final boolean doLowTemp = absoluteRate < getBaseBasalRate(); @@ -263,10 +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(); - ConfigBuilderPlugin configBuilderPlugin = MainApp.getConfigBuilder(); - percent = configBuilderPlugin.applyBasalConstraints(percent); + percent = MainApp.getConstraintChecker().applyBasalPercentConstraints(new Constraint<>(percent), profile).value(); if (percent < 0) { result.isTempCancel = false; result.enacted = false; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java index 336230faf8..fe84ea8114 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgCheckValue_v2.java @@ -3,8 +3,6 @@ package info.nightscout.androidaps.plugins.PumpDanaRv2.comm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -45,17 +43,17 @@ public class MsgCheckValue_v2 extends MessageBase { MainApp.bus().post(new EventNewNotification(notification)); MainApp.getSpecificPlugin(DanaRPlugin.class).disconnect("Wrong Model"); log.debug("Wrong model selected. Switching to Korean DanaR"); - MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentEnabled(PluginBase.PUMP, true); + MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setPluginEnabled(PluginBase.PUMP, true); MainApp.getSpecificPlugin(DanaRKoreanPlugin.class).setFragmentVisible(PluginBase.PUMP, true); - MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentEnabled(PluginBase.PUMP, false); + MainApp.getSpecificPlugin(DanaRPlugin.class).setPluginEnabled(PluginBase.PUMP, false); MainApp.getSpecificPlugin(DanaRPlugin.class).setFragmentVisible(PluginBase.PUMP, false); DanaRPump.reset(); // mark not initialized //If profile coming from pump, switch it as well if(MainApp.getSpecificPlugin(DanaRPlugin.class).isEnabled(PluginBase.PROFILE)){ - (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, false); - (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, true); + (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginBase.PROFILE, false); + (MainApp.getSpecificPlugin(DanaRKoreanPlugin.class)).setPluginEnabled(PluginBase.PROFILE, true); } MainApp.getConfigBuilder().storeSettings(); @@ -70,15 +68,15 @@ public class MsgCheckValue_v2 extends MessageBase { MainApp.bus().post(new EventNewNotification(notification)); DanaRKoreanPlugin.getPlugin().disconnect("Wrong Model"); log.debug("Wrong model selected. Switching to non APS DanaR"); - (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setFragmentEnabled(PluginBase.PUMP, false); + (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setPluginEnabled(PluginBase.PUMP, false); (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setFragmentVisible(PluginBase.PUMP, false); - (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PUMP, true); + (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginBase.PUMP, true); (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentVisible(PluginBase.PUMP, true); //If profile coming from pump, switch it as well if(MainApp.getSpecificPlugin(DanaRv2Plugin.class).isEnabled(PluginBase.PROFILE)){ - (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setFragmentEnabled(PluginBase.PROFILE, false); - (MainApp.getSpecificPlugin(DanaRPlugin.class)).setFragmentEnabled(PluginBase.PROFILE, true); + (MainApp.getSpecificPlugin(DanaRv2Plugin.class)).setPluginEnabled(PluginBase.PROFILE, false); + (MainApp.getSpecificPlugin(DanaRPlugin.class)).setPluginEnabled(PluginBase.PROFILE, true); } MainApp.getConfigBuilder().storeSettings(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpAsyncAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightAsyncAdapter.java similarity index 91% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpAsyncAdapter.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightAsyncAdapter.java index 6f48934059..3759a3f721 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpAsyncAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightAsyncAdapter.java @@ -8,7 +8,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpCallback; +import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightCallback; import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.getWakeLock; import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.msSince; @@ -22,11 +22,11 @@ import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.tsl; * */ -public class InsightPumpAsyncAdapter { +public class InsightAsyncAdapter { - private final ConcurrentHashMap commandResults = new ConcurrentHashMap<>(); + private final ConcurrentHashMap commandResults = new ConcurrentHashMap<>(); - InsightPumpAsyncAdapter() { + InsightAsyncAdapter() { MainApp.bus().register(this); } @@ -36,7 +36,7 @@ public class InsightPumpAsyncAdapter { } @Subscribe - public void onStatusEvent(final EventInsightPumpCallback ev) { + public void onStatusEvent(final EventInsightCallback ev) { log("Received callback event: " + ev.toString()); commandResults.put(ev.request_uuid, ev); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java similarity index 89% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java index 3dfcb9b0a3..156c8271e3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightFragment.java @@ -19,14 +19,14 @@ import java.util.List; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; +import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.utils.StatusItem; import info.nightscout.androidaps.plugins.PumpInsight.utils.ui.StatusItemViewAdapter; import info.nightscout.utils.FabricPrivacy; -public class InsightPumpFragment extends SubscriberFragment { - private static final Logger log = LoggerFactory.getLogger(InsightPumpFragment.class); +public class InsightFragment extends SubscriberFragment { + private static final Logger log = LoggerFactory.getLogger(InsightFragment.class); private static final Handler sLoopHandler = new Handler(); private static volatile boolean refresh = false; private static volatile boolean pending = false; @@ -88,7 +88,7 @@ public class InsightPumpFragment extends SubscriberFragment { @Subscribe - public void onStatusEvent(final EventInsightPumpUpdateGui ev) { + public void onStatusEvent(final EventInsightUpdateGui ev) { updateGUI(); } @@ -99,8 +99,8 @@ public class InsightPumpFragment extends SubscriberFragment { activity.runOnUiThread(new Runnable() { @Override public void run() { - final InsightPumpPlugin insightPumpPlugin = InsightPumpPlugin.getPlugin(); - final List l = insightPumpPlugin.getStatusItems(refresh); + final InsightPlugin insightPlugin = InsightPlugin.getPlugin(); + final List l = insightPlugin.getStatusItems(refresh); holder.removeAllViews(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java similarity index 93% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java index 29bf0b4352..966bf87bb8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java @@ -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.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.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; @@ -41,8 +36,8 @@ import info.nightscout.androidaps.plugins.PumpInsight.connector.Connector; import info.nightscout.androidaps.plugins.PumpInsight.connector.SetTBRTaskRunner; import info.nightscout.androidaps.plugins.PumpInsight.connector.StatusTaskRunner; import info.nightscout.androidaps.plugins.PumpInsight.connector.WriteBasalProfileTaskRunner; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpCallback; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; +import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightCallback; +import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; import info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers; @@ -70,26 +65,25 @@ import static info.nightscout.androidaps.plugins.PumpInsight.history.PumpIdCache /** * Created by jamorham on 23/01/2018. - * + *

* Connects to SightRemote app service using SightParser library - * + *

* SightRemote and SightParser created by Tebbe Ubben - * + *

* Original proof of concept SightProxy by jamorham - * */ @SuppressWarnings("AccessStaticViaInstance") -public class InsightPumpPlugin implements PluginBase, PumpInterface, ConstraintsInterface { +public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInterface { private static final long BUSY_WAIT_TIME = 20000; static Integer batteryPercent = 0; static Integer reservoirInUnits = 0; static boolean initialized = false; private static volatile boolean update_pending = false; - private static Logger log = LoggerFactory.getLogger(InsightPumpPlugin.class); - private static volatile InsightPumpPlugin plugin; - private final InsightPumpAsyncAdapter async = new InsightPumpAsyncAdapter(); + private static Logger log = LoggerFactory.getLogger(InsightPlugin.class); + private static volatile InsightPlugin plugin; + private final InsightAsyncAdapter async = new InsightAsyncAdapter(); private StatusTaskRunner.Result statusResult; private long statusResultTime = -1; private Date lastDataTime = new Date(0); @@ -102,8 +96,8 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints private volatile boolean connector_enabled = false; private List profileBlocks; - private InsightPumpPlugin() { - log("InsightPumpPlugin instantiated"); + private InsightPlugin() { + log("InsightPlugin instantiated"); pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.05d; // specification says 0.05U up to 2U then 0.1U @ 2-5U 0.2U @ 10-20U 0.5U 10-20U (are these just UI restrictions?) @@ -135,7 +129,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints } - public static InsightPumpPlugin getPlugin() { + public static InsightPlugin getPlugin() { if (plugin == null) { createInstance(); } @@ -145,7 +139,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints private static synchronized void createInstance() { if (plugin == null) { log("creating instance"); - plugin = new InsightPumpPlugin(); + plugin = new InsightPlugin(); } } @@ -156,10 +150,10 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints private static void updateGui() { update_pending = false; - MainApp.bus().post(new EventInsightPumpUpdateGui()); + MainApp.bus().post(new EventInsightUpdateGui()); } - private static void pushCallbackEvent(EventInsightPumpCallback e) { + private static void pushCallbackEvent(EventInsightCallback e) { MainApp.bus().post(e); } @@ -190,7 +184,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints @Override public String getFragmentClass() { - return InsightPumpFragment.class.getName(); + return InsightFragment.class.getName(); } @Override @@ -237,7 +231,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PUMP) { if (fragmentEnabled) { enableConnector(); @@ -302,7 +296,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints @Override public void connect(String reason) { - log("InsightPumpPlugin::connect()"); + log("InsightPlugin::connect()"); try { if (!connector.isPumpConnected()) { if (Helpers.ratelimit("insight-connect-timer", 40)) { @@ -324,7 +318,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints @Override public void disconnect(String reason) { - log("InsightPumpPlugin::disconnect()"); + log("InsightPlugin::disconnect()"); try { if (!SP.getBoolean("insight_always_connected", false)) { log("Requesting disconnect"); @@ -339,7 +333,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints @Override public void stopConnecting() { - log("InsightPumpPlugin::stopConnecting()"); + log("InsightPlugin::stopConnecting()"); try { if (isConnecting()) { if (!SP.getBoolean("insight_always_connected", false)) { @@ -367,7 +361,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints Mstatus mstatus = async.busyWaitForCommandResult(uuid, BUSY_WAIT_TIME); if (mstatus.success()) { log("GOT STATUS RESULT!!! PARTY WOOHOO!!!"); - statusResult = (StatusTaskRunner.Result) mstatus.getResponseObject(); + setStatusResult((StatusTaskRunner.Result) mstatus.getResponseObject()); statusResultTime = Helpers.tsl(); processStatusResult(); updateGui(); @@ -387,6 +381,10 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints } } + public void setStatusResult(StatusTaskRunner.Result result) { + this.statusResult = result; + } + @Override public PumpEnactResult setNewBasalProfile(Profile profile) { PumpEnactResult result = new PumpEnactResult(); @@ -402,7 +400,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)); } @@ -432,12 +431,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; } @@ -492,7 +494,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints Treatment t = new Treatment(); t.isSMB = detailedBolusInfo.isSMB; final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance(); - bolusingEvent.t = t; + bolusingEvent.t = t; bolusingEvent.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), 0F); bolusingEvent.bolusId = bolusId; bolusingEvent.percent = 0; @@ -524,9 +526,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())); @@ -555,7 +560,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints // Temporary Basals @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { absoluteRate = Helpers.roundDouble(absoluteRate, 3); log("Set TBR absolute: " + absoluteRate); final double base_basal = getBaseBasalRate(); @@ -574,7 +579,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"); @@ -619,7 +623,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; @@ -1014,7 +1018,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints // if (!isConnected()) return false; //if (isBusy()) return false; log("asyncSinglecommand called: " + name); - final EventInsightPumpCallback event = new EventInsightPumpCallback(); + final EventInsightCallback event = new EventInsightCallback(); new Thread() { @Override public void run() { @@ -1053,7 +1057,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints // if (!isConnected()) return false; //if (isBusy()) return false; log("asyncTaskRunner called: " + name); - final EventInsightPumpCallback event = new EventInsightPumpCallback(); + final EventInsightCallback event = new EventInsightCallback(); new Thread() { @Override public void run() { @@ -1092,54 +1096,26 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints // Constraints @Override - public boolean isLoopEnabled() { - return true; + public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { + if (statusResult != null) { + absoluteRate.setIfSmaller(statusResult.maximumBasalAmount, String.format(MainApp.gs(R.string.limitingbasalratio), statusResult.maximumBasalAmount, MainApp.gs(R.string.pumplimit)), this); + } + return absoluteRate; } @Override - public boolean isClosedModeEnabled() { - return true; + public Constraint applyBasalPercentConstraints(Constraint percentRate, Profile profile) { + percentRate.setIfGreater(0, String.format(MainApp.gs(R.string.limitingpercentrate), 0, MainApp.gs(R.string.itmustbepositivevalue)), this); + percentRate.setIfSmaller(getPumpDescription().maxTempPercent, String.format(MainApp.gs(R.string.limitingpercentrate), getPumpDescription().maxTempPercent, MainApp.gs(R.string.pumplimit)), this); + + return percentRate; } @Override - public boolean isAutosensModeEnabled() { - return true; + public Constraint applyBolusConstraints(Constraint insulin) { + if (statusResult != null) + insulin.setIfSmaller(statusResult.maximumBolusAmount, String.format(MainApp.gs(R.string.limitingbolus), statusResult.maximumBolusAmount, MainApp.gs(R.string.pumplimit)), this); + return insulin; } - @Override - public boolean isAMAModeEnabled() { - return true; - } - - @Override - public boolean isSMBModeEnabled() { - return true; - } - - @Override - public Double applyBasalConstraints(Double absoluteRate) { - return Math.min(absoluteRate, statusResult != null ? statusResult.maximumBasalAmount : 0); - } - - @Override - public Integer applyBasalConstraints(Integer percentRate) { - return Math.min(percentRate, pumpDescription.maxTempPercent); - } - - @Override - public Double applyBolusConstraints(Double insulin) { - return Math.min(insulin, statusResult != null ? statusResult.maximumBolusAmount : 0); - } - - @Override - public Integer applyCarbsConstraints(Integer carbs) { - return carbs; - } - - @Override - public Double applyMaxIOBConstraints(Double maxIob) { - return maxIob; - } - - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java index 57e6da7f2a..8797325f7c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/Mstatus.java @@ -1,6 +1,6 @@ package info.nightscout.androidaps.plugins.PumpInsight; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpCallback; +import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightCallback; /** * Created by jamorham on 01/02/2018. @@ -11,7 +11,7 @@ import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpCal class Mstatus { Cstatus cstatus = Cstatus.UNKNOWN; - EventInsightPumpCallback event; + EventInsightCallback event; // comment field preparation for results String getCommandComment() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java index 311e487b9f..a96c98a39a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java @@ -14,7 +14,7 @@ import java.util.Map; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.EventFeatureRunning; -import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; +import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; import info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers; @@ -76,7 +76,7 @@ public class Connector { extendKeepAliveIfActive(); } - MainApp.bus().post(new EventInsightPumpUpdateGui()); + MainApp.bus().post(new EventInsightUpdateGui()); } else { log("Same status as before: " + status); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightPumpCallback.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java similarity index 86% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightPumpCallback.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java index 964270cb45..16cb5af457 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightPumpCallback.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightCallback.java @@ -7,7 +7,7 @@ import info.nightscout.androidaps.events.Event; /** * Created by jamorham on 23/01/2018. */ -public class EventInsightPumpCallback extends Event { +public class EventInsightCallback extends Event { public UUID request_uuid; public boolean success = false; @@ -15,7 +15,7 @@ public class EventInsightPumpCallback extends Event { public int response_id = -1; public Object response_object = null; - public EventInsightPumpCallback() { + public EventInsightCallback() { request_uuid = UUID.randomUUID(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightPumpUpdateGui.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightUpdateGui.java similarity index 72% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightPumpUpdateGui.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightUpdateGui.java index 79e975ac31..3741c607c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightPumpUpdateGui.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/events/EventInsightUpdateGui.java @@ -5,5 +5,5 @@ import info.nightscout.androidaps.events.EventUpdateGui; /** * Created by jamorham on 23/01/2018. */ -public class EventInsightPumpUpdateGui extends EventUpdateGui { +public class EventInsightUpdateGui extends EventUpdateGui { } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java index b435dd605a..a7edff8c52 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpMDI/MDIPlugin.java @@ -90,7 +90,7 @@ public class MDIPlugin implements PluginBase, PumpInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PUMP) this.fragmentEnabled = fragmentEnabled; } @@ -201,7 +201,7 @@ public class MDIPlugin implements PluginBase, PumpInterface { } @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { PumpEnactResult result = new PumpEnactResult(); result.success = false; result.comment = MainApp.instance().getString(R.string.pumperror); @@ -211,7 +211,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); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index dc81b47c21..7643796cbe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -98,7 +98,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { pumpDescription.basalStep = 0.01d; pumpDescription.basalMinimumRate = 0.01d; - pumpDescription.isRefillingCapable = false; + pumpDescription.isRefillingCapable = true; pumpDescription.storesCarbInfo = false; pumpDescription.is30minBasalRatesCapable = true; @@ -151,7 +151,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == PUMP) this.fragmentEnabled = fragmentEnabled; } @@ -296,7 +296,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { } @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean enforceNew) { + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); TemporaryBasal tempBasal = new TemporaryBasal(); tempBasal.date = System.currentTimeMillis(); @@ -320,7 +320,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()) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java index 067ecdef8f..e321e98f1e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java @@ -88,7 +88,7 @@ public class SensitivityAAPSPlugin implements PluginBase, SensitivityInterface{ } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java index 5c6188788c..bcac02f51c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java @@ -87,7 +87,7 @@ public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java index d80510d8a8..7b2592c7e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java @@ -84,7 +84,7 @@ public class SensitivityWeightedAveragePlugin implements PluginBase, Sensitivity } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == SENSITIVITY) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java index 01f883e6d6..a67c8d4212 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java @@ -29,11 +29,12 @@ import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshOverview; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; @@ -176,7 +177,7 @@ public class SmsCommunicatorPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) this.fragmentEnabled = fragmentEnabled; } @@ -285,7 +286,7 @@ public class SmsCommunicatorPlugin implements PluginBase { case "STOP": LoopPlugin loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); if (loopPlugin != null && loopPlugin.isEnabled(PluginBase.LOOP)) { - loopPlugin.setFragmentEnabled(PluginBase.LOOP, false); + loopPlugin.setPluginEnabled(PluginBase.LOOP, false); ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { @@ -303,7 +304,7 @@ public class SmsCommunicatorPlugin implements PluginBase { case "START": loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); if (loopPlugin != null && !loopPlugin.isEnabled(PluginBase.LOOP)) { - loopPlugin.setFragmentEnabled(PluginBase.LOOP, true); + loopPlugin.setPluginEnabled(PluginBase.LOOP, true); reply = MainApp.sResources.getString(R.string.smscommunicator_loophasbeenenabled); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); @@ -418,18 +419,24 @@ public class SmsCommunicatorPlugin implements PluginBase { } } else { tempBasal = SafeParse.stringToDouble(splited[1]); - tempBasal = MainApp.getConfigBuilder().applyBasalConstraints(tempBasal); - if (remoteCommandsAllowed) { - passCode = generatePasscode(); - reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); - receivedSms.processed = true; - resetWaitingMessages(); - sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); - tempBasalWaitingForConfirmation.tempBasal = tempBasal; - FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); - } else { - reply = MainApp.sResources.getString(R.string.smscommunicator_remotebasalnotallowed); + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) { + reply = MainApp.sResources.getString(R.string.noprofile); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + } else { + tempBasal = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(tempBasal), profile).value(); + if (remoteCommandsAllowed) { + passCode = generatePasscode(); + reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode); + receivedSms.processed = true; + resetWaitingMessages(); + sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); + tempBasalWaitingForConfirmation.tempBasal = tempBasal; + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); + } else { + reply = MainApp.sResources.getString(R.string.smscommunicator_remotebasalnotallowed); + sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + } } } } @@ -443,7 +450,7 @@ public class SmsCommunicatorPlugin implements PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); } else if (splited.length > 1) { amount = SafeParse.stringToDouble(splited[1]); - amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); + amount = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); if (amount > 0d && remoteCommandsAllowed) { passCode = generatePasscode(); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_bolusreplywithcode), amount, passCode); @@ -503,20 +510,22 @@ public class SmsCommunicatorPlugin implements PluginBase { } else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed && tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - tempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { tempBasalWaitingForConfirmation.processed = true; - ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(tempBasalWaitingForConfirmation.tempBasal, 30, true, new Callback() { - @Override - public void run() { - if (result.success) { - String reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); - } else { - String reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalfailed); - reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); - sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile != null) + ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(tempBasalWaitingForConfirmation.tempBasal, 30, true, profile, new Callback() { + @Override + public void run() { + if (result.success) { + String reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalset), result.absolute, result.duration); + reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); + } else { + String reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalfailed); + reply += "\n" + ConfigBuilderPlugin.getActivePump().shortStatus(true); + sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); + } } - } - }); + }); } else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed && cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && System.currentTimeMillis() - cancelTempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) { cancelTempBasalWaitingForConfirmation.processed = true; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java index 8b9734cb79..719b2eb1f4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java @@ -68,7 +68,7 @@ public class SourceDexcomG5Plugin implements PluginBase, BgSourceInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java index eb9a6b1c6b..719a4b3059 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceGlimp/SourceGlimpPlugin.java @@ -68,7 +68,7 @@ public class SourceGlimpPlugin implements PluginBase, BgSourceInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java index 1111c8c9eb..38b787d750 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceMM640g/SourceMM640gPlugin.java @@ -68,7 +68,7 @@ public class SourceMM640gPlugin implements PluginBase, BgSourceInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java index f43c44047e..bbc1759735 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceNSClient/SourceNSClientPlugin.java @@ -70,7 +70,7 @@ public class SourceNSClientPlugin implements PluginBase, BgSourceInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java index 532492d40e..66e8d470fd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceXdrip/SourceXdripPlugin.java @@ -69,7 +69,7 @@ public class SourceXdripPlugin implements PluginBase, BgSourceInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == BGSOURCE) this.fragmentEnabled = fragmentEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java index 4bf96f470b..9f62e1a7d8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java @@ -57,11 +57,11 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { private IobTotal lastTreatmentCalculation; private IobTotal lastTempBasalsCalculation; - public static List treatments; - private static Intervals tempBasals = new NonOverlappingIntervals<>(); - private static Intervals extendedBoluses = new NonOverlappingIntervals<>(); - private static Intervals tempTargets = new OverlappingIntervals<>(); - private static ProfileIntervals profiles = new ProfileIntervals<>(); + private final static ArrayList treatments = new ArrayList<>(); + private final static Intervals tempBasals = new NonOverlappingIntervals<>(); + private final static Intervals extendedBoluses = new NonOverlappingIntervals<>(); + private final static Intervals tempTargets = new OverlappingIntervals<>(); + private final static ProfileIntervals profiles = new ProfileIntervals<>(); private boolean fragmentEnabled = true; private boolean fragmentVisible = true; @@ -113,7 +113,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == TREATMENT) this.fragmentEnabled = fragmentEnabled; } @@ -146,8 +146,10 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null) dia = MainApp.getConfigBuilder().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); - - treatments = MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false); + synchronized (treatments) { + treatments.clear(); + treatments.addAll(MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false)); + } } private static void initializeTempBasalData() { @@ -156,7 +158,9 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { dia = MainApp.getConfigBuilder().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); - tempBasals.reset().add(MainApp.getDbHelper().getTemporaryBasalsDataFromTime(fromMills, false)); + synchronized (tempBasals) { + tempBasals.reset().add(MainApp.getDbHelper().getTemporaryBasalsDataFromTime(fromMills, false)); + } } @@ -166,17 +170,23 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { dia = MainApp.getConfigBuilder().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); - extendedBoluses.reset().add(MainApp.getDbHelper().getExtendedBolusDataFromTime(fromMills, false)); + synchronized (extendedBoluses) { + extendedBoluses.reset().add(MainApp.getDbHelper().getExtendedBolusDataFromTime(fromMills, false)); + } } private void initializeTempTargetData() { - long fromMills = System.currentTimeMillis() - 60 * 60 * 1000L * 24; - tempTargets.reset().add(MainApp.getDbHelper().getTemptargetsDataFromTime(fromMills, false)); + synchronized (tempTargets) { + long fromMills = System.currentTimeMillis() - 60 * 60 * 1000L * 24; + tempTargets.reset().add(MainApp.getDbHelper().getTemptargetsDataFromTime(fromMills, false)); + } } private void initializeProfileSwitchData() { - profiles.reset().add(MainApp.getDbHelper().getProfileSwitchData(false)); + synchronized (profiles) { + profiles.reset().add(MainApp.getDbHelper().getProfileSwitchData(false)); + } } @Override @@ -194,22 +204,24 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { double dia = profile.getDia(); - for (Integer pos = 0; pos < treatments.size(); pos++) { - Treatment t = treatments.get(pos); - if (!t.isValid) continue; - if (t.date > time) continue; - Iob tIOB = t.iobCalc(time, dia); - total.iob += tIOB.iobContrib; - total.activity += tIOB.activityContrib; - if (t.date > total.lastBolusTime) - total.lastBolusTime = t.date; - if (!t.isSMB) { - // instead of dividing the DIA that only worked on the bilinear curves, - // multiply the time the treatment is seen active. - long timeSinceTreatment = time - t.date; - long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0)); - Iob bIOB = t.iobCalc(snoozeTime, dia); - total.bolussnooze += bIOB.iobContrib; + synchronized (treatments) { + for (Integer pos = 0; pos < treatments.size(); pos++) { + Treatment t = treatments.get(pos); + if (!t.isValid) continue; + if (t.date > time) continue; + Iob tIOB = t.iobCalc(time, dia); + total.iob += tIOB.iobContrib; + total.activity += tIOB.activityContrib; + if (t.date > total.lastBolusTime) + total.lastBolusTime = t.date; + if (!t.isSMB) { + // instead of dividing the DIA that only worked on the bilinear curves, + // multiply the time the treatment is seen active. + long timeSinceTreatment = time - t.date; + long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0)); + Iob bIOB = t.iobCalc(snoozeTime, dia); + total.bolussnooze += bIOB.iobContrib; + } } } @@ -240,17 +252,19 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { long now = System.currentTimeMillis(); long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue(); - for (Treatment treatment : treatments) { - if (!treatment.isValid) - continue; - long t = treatment.date; - if (t > dia_ago && t <= now) { - if (treatment.carbs >= 1) { - result.carbs += treatment.carbs; - result.lastCarbTime = t; - } - if (treatment.insulin > 0 && treatment.mealBolus) { - result.boluses += treatment.insulin; + synchronized (treatments) { + for (Treatment treatment : treatments) { + if (!treatment.isValid) + continue; + long t = treatment.date; + if (t > dia_ago && t <= now) { + if (treatment.carbs >= 1) { + result.carbs += treatment.carbs; + result.lastCarbTime = t; + } + if (treatment.insulin > 0 && treatment.mealBolus) { + result.boluses += treatment.insulin; + } } } } @@ -267,29 +281,35 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public List getTreatmentsFromHistory() { - return treatments; + synchronized (treatments) { + return (List) treatments.clone(); + } } @Override public List getTreatments5MinBackFromHistory(long time) { List in5minback = new ArrayList<>(); - for (Integer pos = 0; pos < treatments.size(); pos++) { - Treatment t = treatments.get(pos); - if (!t.isValid) - continue; - if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0) - in5minback.add(t); + synchronized (treatments) { + for (Integer pos = 0; pos < treatments.size(); pos++) { + Treatment t = treatments.get(pos); + if (!t.isValid) + continue; + if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0) + in5minback.add(t); + } + return in5minback; } - return in5minback; } @Override public long getLastBolusTime() { long now = System.currentTimeMillis(); long last = 0; - for (Treatment t : treatments) { - if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now) - last = t.date; + synchronized (treatments) { + for (Treatment t : treatments) { + if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now) + last = t.date; + } } log.debug("Last bolus time: " + new Date(last).toLocaleString()); return last; @@ -302,7 +322,9 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public TemporaryBasal getRealTempBasalFromHistory(long time) { - return tempBasals.getValueByInterval(time); + synchronized (tempBasals) { + return tempBasals.getValueByInterval(time); + } } @Override @@ -401,7 +423,9 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public ExtendedBolus getExtendedBolusFromHistory(long time) { - return extendedBoluses.getValueByInterval(time); + synchronized (extendedBoluses) { + return extendedBoluses.getValueByInterval(time); + } } @Override @@ -412,12 +436,16 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public Intervals getExtendedBolusesFromHistory() { - return extendedBoluses; + synchronized (extendedBoluses) { + return new NonOverlappingIntervals<>(extendedBoluses); + } } @Override public Intervals getTemporaryBasalsFromHistory() { - return tempBasals; + synchronized (tempBasals) { + return new NonOverlappingIntervals<>(tempBasals); + } } @Override @@ -482,18 +510,24 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Nullable @Override public TempTarget getTempTargetFromHistory() { - return tempTargets.getValueByInterval(System.currentTimeMillis()); + synchronized (tempTargets) { + return tempTargets.getValueByInterval(System.currentTimeMillis()); + } } @Nullable @Override public TempTarget getTempTargetFromHistory(long time) { - return tempTargets.getValueByInterval(time); + synchronized (tempTargets) { + return tempTargets.getValueByInterval(time); + } } @Override public Intervals getTempTargetsFromHistory() { - return tempTargets; + synchronized (tempTargets) { + return new NonOverlappingIntervals<>(tempTargets); + } } // Profile Switch @@ -504,12 +538,16 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public ProfileSwitch getProfileSwitchFromHistory(long time) { - return (ProfileSwitch) profiles.getValueToTime(time); + synchronized (profiles) { + return (ProfileSwitch) profiles.getValueToTime(time); + } } @Override public ProfileIntervals getProfileSwitchesFromHistory() { - return profiles; + synchronized (profiles) { + return new ProfileIntervals<>(profiles); + } } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java index baf1e43d55..6831ee33f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java @@ -76,7 +76,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. return; Treatment t = treatments.get(position); holder.date.setText(DateUtil.dateAndTimeString(t.date)); - holder.insulin.setText(DecimalFormatter.to2Decimal(t.insulin) + " U"); + holder.insulin.setText(DecimalFormatter.toPumpSupportedBolus(t.insulin) + " U"); holder.carbs.setText(DecimalFormatter.to0Decimal(t.carbs) + " g"); Iob iob = t.iobCalc(System.currentTimeMillis(), profile.getDia()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iobContrib) + " U"); @@ -176,7 +176,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. llm = new LinearLayoutManager(view.getContext()); recyclerView.setLayoutManager(llm); - RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.treatments); + RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()); recyclerView.setAdapter(adapter); iobTotal = (TextView) view.findViewById(R.id.treatments_iobtotal); @@ -232,7 +232,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. activity.runOnUiThread(new Runnable() { @Override public void run() { - recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.treatments), false); + recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false); if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) { iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U"); activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java index 1cb6d04614..2bf7684c94 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java @@ -80,7 +80,7 @@ public class TreatmentsExtendedBolusesFragment extends SubscriberFragment { holder.date.setText(DateUtil.dateAndTimeString(extendedBolus.date) + " - " + DateUtil.timeString(extendedBolus.end())); } holder.duration.setText(DecimalFormatter.to0Decimal(extendedBolus.durationInMinutes) + " min"); - holder.insulin.setText(DecimalFormatter.to2Decimal(extendedBolus.insulin) + " U"); + holder.insulin.setText(DecimalFormatter.toPumpSupportedBolus(extendedBolus.insulin) + " U"); holder.realDuration.setText(DecimalFormatter.to0Decimal(extendedBolus.getRealDuration()) + " min"); IobTotal iob = extendedBolus.iobCalc(System.currentTimeMillis()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iob) + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java index 1c050fe7d0..0adb6f2055 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java @@ -1,6 +1,5 @@ package info.nightscout.androidaps.plugins.Wear; -import android.Manifest; import android.os.HandlerThread; import android.support.annotation.NonNull; @@ -28,8 +27,8 @@ import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.APSInterface; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Actions.dialogs.FillDialog; import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; @@ -96,7 +95,7 @@ public class ActionStringHandler { } else { return; } - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(amount); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); rMessage += MainApp.instance().getString(R.string.primefill) + ": " + insulinAfterConstraints + "U"; if (insulinAfterConstraints - amount != 0) rMessage += "\n" + MainApp.instance().getString(R.string.constraintapllied); @@ -107,7 +106,7 @@ public class ActionStringHandler { ////////////////////////////////////////////// PRIME/FILL double amount = SafeParse.stringToDouble(act[1]); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(amount); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); rMessage += MainApp.instance().getString(R.string.primefill) + ": " + insulinAfterConstraints + "U"; if (insulinAfterConstraints - amount != 0) rMessage += "\n" + MainApp.instance().getString(R.string.constraintapllied); @@ -118,8 +117,8 @@ public class ActionStringHandler { ////////////////////////////////////////////// BOLUS double insulin = SafeParse.stringToDouble(act[1]); int carbs = SafeParse.stringToInt(act[2]); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin); - Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); + Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbs)).value(); rMessage += MainApp.instance().getString(R.string.bolus) + ": " + insulinAfterConstraints + "U\n"; rMessage += MainApp.instance().getString(R.string.carbs) + ": " + carbsAfterConstraints + "g"; @@ -183,7 +182,7 @@ public class ActionStringHandler { } else if ("wizard".equals(act[0])) { ////////////////////////////////////////////// WIZARD Integer carbsBeforeConstraints = SafeParse.stringToInt(act[1]); - Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbsBeforeConstraints); + Integer carbsAfterConstraints = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>(carbsBeforeConstraints)).value(); if (carbsAfterConstraints - carbsBeforeConstraints != 0) { sendError("Carb constraint violation!"); @@ -211,7 +210,7 @@ public class ActionStringHandler { BolusWizard bolusWizard = new BolusWizard(); bolusWizard.doCalc(profile, null, carbsAfterConstraints, 0d, useBG ? bgReading.valueToUnits(profile.getUnits()) : 0d, 0d, percentage, useBolusIOB, useBasalIOB, false, false); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(bolusWizard.calculatedTotalInsulin); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(bolusWizard.calculatedTotalInsulin)).value(); if (insulinAfterConstraints - bolusWizard.calculatedTotalInsulin != 0) { sendError("Insulin contraint violation!" + "\nCannot deliver " + format.format(bolusWizard.calculatedTotalInsulin) + "!"); @@ -445,7 +444,7 @@ public class ActionStringHandler { // decide if enabled/disabled closed/open; what Plugin as APS? final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop(); if (activeloop != null && activeloop.isEnabled(activeloop.getType())) { - if (MainApp.getConfigBuilder().isClosedModeEnabled()) { + if (MainApp.getConstraintChecker().isClosedLoopAllowed().value()) { ret += "CLOSED LOOP\n"; } else { ret += "OPEN LOOP\n"; @@ -545,7 +544,7 @@ public class ActionStringHandler { if ("fill".equals(act[0])) { Double amount = SafeParse.stringToDouble(act[1]); - Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(amount); + Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(amount)).value(); if (amount - insulinAfterConstraints != 0) { ToastUtils.showToastInUiThread(MainApp.instance(), "aborting: previously applied constraint changed"); sendError("aborting: previously applied constraint changed"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java index bc44c75911..f37effebe3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java @@ -107,7 +107,7 @@ public class WearPlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) { this.fragmentEnabled = fragmentEnabled; if (watchUS != null) { @@ -182,8 +182,7 @@ public class WearPlugin implements PluginBase { @Subscribe public void onStatusEvent(final EventNewBG ev) { - if (ev.isFromActiveBgSource) - sendDataToWatch(true, true, true); + sendDataToWatch(true, true, true); } @Subscribe diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java index f1fd58c3f9..d2df702cd4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java @@ -117,7 +117,7 @@ public class StatuslinePlugin implements PluginBase { } @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { + public void setPluginEnabled(int type, boolean fragmentEnabled) { if (type == GENERAL) { this.fragmentEnabled = fragmentEnabled; @@ -235,8 +235,7 @@ public class StatuslinePlugin implements PluginBase { @Subscribe public void onStatusEvent(final EventNewBG ev) { - if (ev.isFromActiveBgSource && ev.isNew && ev.isCurrent()) - sendStatus(); + sendStatus(); } @Subscribe diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java index f41ec90f27..d8d4102828 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.java @@ -18,13 +18,14 @@ import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.events.EventBolusRequested; +import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressHelperActivity; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; 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.queue.commands.Command; import info.nightscout.androidaps.queue.commands.CommandBolus; import info.nightscout.androidaps.queue.commands.CommandCancelExtendedBolus; @@ -166,8 +167,8 @@ public class CommandQueue { removeAll(type); // apply constraints - detailedBolusInfo.insulin = MainApp.getConfigBuilder().applyBolusConstraints(detailedBolusInfo.insulin); - detailedBolusInfo.carbs = MainApp.getConfigBuilder().applyCarbsConstraints((int) detailedBolusInfo.carbs); + detailedBolusInfo.insulin = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); + detailedBolusInfo.carbs = MainApp.getConstraintChecker().applyCarbsConstraints(new Constraint<>((int) detailedBolusInfo.carbs)).value(); // add new command to queue if (detailedBolusInfo.isSMB) { @@ -187,7 +188,7 @@ public class CommandQueue { } // returns true if command is queued - public boolean tempBasalAbsolute(double absoluteRate, int durationInMinutes, boolean enforceNew, Callback callback) { + public boolean tempBasalAbsolute(double absoluteRate, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) { if (isRunning(Command.CommandType.TEMPBASAL)) { if (callback != null) callback.result(executingNowError()).run(); @@ -197,10 +198,10 @@ public class CommandQueue { // remove all unfinished removeAll(Command.CommandType.TEMPBASAL); - Double rateAfterConstraints = MainApp.getConfigBuilder().applyBasalConstraints(absoluteRate); + Double rateAfterConstraints = MainApp.getConstraintChecker().applyBasalConstraints(new Constraint<>(absoluteRate), profile).value(); // add new command to queue - add(new CommandTempBasalAbsolute(rateAfterConstraints, durationInMinutes, enforceNew, callback)); + add(new CommandTempBasalAbsolute(rateAfterConstraints, durationInMinutes, enforceNew, profile, callback)); notifyAboutNewCommand(); @@ -208,7 +209,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 +219,10 @@ public class CommandQueue { // remove all unfinished removeAll(Command.CommandType.TEMPBASAL); - Integer percentAfterConstraints = MainApp.getConfigBuilder().applyBasalConstraints(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(); @@ -236,7 +237,7 @@ public class CommandQueue { return false; } - Double rateAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin); + Double rateAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); // remove all unfinished removeAll(Command.CommandType.EXTENDEDBOLUS); diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java index 28dc728174..35c2435558 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalAbsolute.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; +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; @@ -19,18 +20,20 @@ public class CommandTempBasalAbsolute extends Command { int durationInMinutes; double absoluteRate; boolean enforceNew; + Profile profile; - public CommandTempBasalAbsolute(double absoluteRate, int durationInMinutes, boolean enforceNew, Callback callback) { + public CommandTempBasalAbsolute(double absoluteRate, int durationInMinutes, boolean enforceNew, Profile profile, Callback callback) { commandType = CommandType.TEMPBASAL; this.absoluteRate = absoluteRate; this.durationInMinutes = durationInMinutes; this.enforceNew = enforceNew; + this.profile = profile; this.callback = callback; } @Override public void execute() { - PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setTempBasalAbsolute(absoluteRate, durationInMinutes, enforceNew); + PumpEnactResult r = ConfigBuilderPlugin.getActivePump().setTempBasalAbsolute(absoluteRate, durationInMinutes, profile, enforceNew); if (Config.logCongigBuilderActions) log.debug("setTempBasalAbsolute rate: " + absoluteRate + " durationInMinutes: " + durationInMinutes + " success: " + r.success + " enacted: " + r.enacted); if (callback != null) diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java index 15f8849cd2..bbb421e128 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandTempBasalPercent.java @@ -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) diff --git a/app/src/main/java/info/nightscout/utils/DecimalFormatter.java b/app/src/main/java/info/nightscout/utils/DecimalFormatter.java index 1a70b43c30..d821f5ba37 100644 --- a/app/src/main/java/info/nightscout/utils/DecimalFormatter.java +++ b/app/src/main/java/info/nightscout/utils/DecimalFormatter.java @@ -2,6 +2,8 @@ package info.nightscout.utils; import java.text.DecimalFormat; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; + /** * Created by mike on 11.07.2016. */ @@ -26,4 +28,16 @@ public class DecimalFormatter { public static String to3Decimal(double value) { return format3dec.format(value); } + + public static String toPumpSupportedBolus(double value) { + return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01 + ? to2Decimal(value) + : to1Decimal(value); + } + + public static DecimalFormat pumpSupportedBolusFormat() { + return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01 + ? new DecimalFormat("0.00") + : new DecimalFormat("0.0"); + } } diff --git a/app/src/main/java/info/nightscout/utils/HardLimits.java b/app/src/main/java/info/nightscout/utils/HardLimits.java index 00e42ce535..8e1a05db0d 100644 --- a/app/src/main/java/info/nightscout/utils/HardLimits.java +++ b/app/src/main/java/info/nightscout/utils/HardLimits.java @@ -18,7 +18,7 @@ public class HardLimits { final static int ADULT = 2; final static int RESISTANTADULT = 3; - final static double[] MAXBOLUS = {5d, 10d, 17d, 21d}; + final static double[] MAXBOLUS = {5d, 10d, 17d, 25d}; // Very Hard Limits Ranges // First value is the Lowest and second value is the Highest a Limit can define @@ -40,7 +40,7 @@ public class HardLimits { public static final double MAXISF = 720; // mgdl public static final double[] MAXIOB_AMA = {3, 5, 7, 12}; - public static final double[] MAXIOB_SMB = {3, 7, 12, 22}; + public static final double[] MAXIOB_SMB = {3, 7, 12, 25}; public static final double[] MAXBASAL = {2, 5, 10, 12}; @@ -49,13 +49,13 @@ public class HardLimits { String sp_age = SP.getString(R.string.key_age, ""); int age; - if (sp_age.equals(MainApp.sResources.getString(R.string.key_child))) + if (sp_age.equals(MainApp.gs(R.string.key_child))) age = CHILD; - else if (sp_age.equals(MainApp.sResources.getString(R.string.key_teenage))) + else if (sp_age.equals(MainApp.gs(R.string.key_teenage))) age = TEENAGE; - else if (sp_age.equals(MainApp.sResources.getString(R.string.key_adult))) + else if (sp_age.equals(MainApp.gs(R.string.key_adult))) age = ADULT; - else if (sp_age.equals(MainApp.sResources.getString(R.string.key_resistantadult))) + else if (sp_age.equals(MainApp.gs(R.string.key_resistantadult))) age = RESISTANTADULT; else age = ADULT; @@ -88,9 +88,9 @@ public class HardLimits { if (newvalue < lowLimit || newvalue > highLimit) { newvalue = Math.max(newvalue, lowLimit); newvalue = Math.min(newvalue, highLimit); - String msg = String.format(MainApp.sResources.getString(R.string.valueoutofrange), valueName); + String msg = String.format(MainApp.gs(R.string.valueoutofrange), valueName); msg += ".\n"; - msg += String.format(MainApp.sResources.getString(R.string.valuelimitedto), value, newvalue); + msg += String.format(MainApp.gs(R.string.valuelimitedto), value, newvalue); log.error(msg); NSUpload.uploadError(msg); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); diff --git a/app/src/main/java/info/nightscout/utils/NSUpload.java b/app/src/main/java/info/nightscout/utils/NSUpload.java index a75377aae1..b33d3e2808 100644 --- a/app/src/main/java/info/nightscout/utils/NSUpload.java +++ b/app/src/main/java/info/nightscout/utils/NSUpload.java @@ -475,6 +475,27 @@ public class NSUpload { } } + public static void uploadEvent(String careportalEvent, long time) { + Context context = MainApp.instance().getApplicationContext(); + Bundle bundle = new Bundle(); + bundle.putString("action", "dbAdd"); + bundle.putString("collection", "treatments"); + JSONObject data = new JSONObject(); + try { + data.put("eventType", careportalEvent); + data.put("created_at", DateUtil.toISOString(time)); + data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name))); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + bundle.putString("data", data.toString()); + Intent intent = new Intent(Intents.ACTION_DATABASE); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + DbLogger.dbAdd(intent, data.toString()); + } + public static void removeFoodFromNS(String _id) { try { Context context = MainApp.instance().getApplicationContext(); diff --git a/app/src/main/res/layout/actions_fill_dialog.xml b/app/src/main/res/layout/actions_fill_dialog.xml index 55e44f4bc7..18a5886246 100644 --- a/app/src/main/res/layout/actions_fill_dialog.xml +++ b/app/src/main/res/layout/actions_fill_dialog.xml @@ -1,110 +1,97 @@ - + - - - + android:orientation="vertical" + android:focusableInTouchMode="true" + android:padding="10dp"> - + - + - + - + -