diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 8a114bcc13..089ffa255e 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -31,7 +31,6 @@ 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; @@ -188,7 +187,7 @@ public class MainApp extends Application { pluginsList.add(new PersistentNotificationPlugin(this)); pluginsList.add(NSClientPlugin.getPlugin()); - pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin()); + pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin()); MainApp.getConfigBuilder().initialize(); } 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 5faa288d77..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; diff --git a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java index d984e3277f..6c13075a3c 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java @@ -4,9 +4,11 @@ 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. @@ -41,6 +43,10 @@ public class ConstraintChecker implements ConstraintsInterface { 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); } @@ -121,6 +127,17 @@ public class ConstraintChecker implements ConstraintsInterface { 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); 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 00c502ec40..caf15b5b90 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java @@ -66,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; 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 4918cbfacf..a1daa08a56 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java @@ -27,6 +27,10 @@ public interface ConstraintsInterface { return value; } + default Constraint isAdvancedFilteringEnabled(Constraint value) { + return value; + } + default Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { return absoluteRate; } 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 fd224531b4..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.setPluginEnabled(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 { @@ -317,7 +295,7 @@ public class ConfigBuilderFragment extends Fragment { if (pluginList.size() < 2) { holder.checkboxEnabled.setEnabled(false); plugin.setPluginEnabled(type, true); - getPlugin().storeSettings(); + ConfigBuilderPlugin.getPlugin().storeSettings(); } // Constraints cannot be disabled @@ -396,17 +374,17 @@ public class ConfigBuilderFragment extends Fragment { } } else { // enable first plugin in list if (type == PluginBase.PUMP) - MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setPluginEnabled(type, true); + VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.INSULIN) - MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setPluginEnabled(type, true); + InsulinFastactingPlugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.SENSITIVITY) - MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setPluginEnabled(type, true); + SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.PROFILE) - MainApp.getSpecificPlugin(NSProfilePlugin.class).setPluginEnabled(type, true); + NSProfilePlugin.getPlugin().setPluginEnabled(type, true); else 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 cd2794b3be..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 @@ -23,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; @@ -58,7 +59,15 @@ import info.nightscout.utils.ToastUtils; 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; @@ -197,7 +206,7 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { return commandQueue; } - public static BgSourceInterface getActiveBgSource() { + public BgSourceInterface getActiveBgSource() { return activeBgSource; } @@ -657,9 +666,12 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { 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); 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 5c792c9405..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 @@ -5,7 +5,9 @@ import org.slf4j.LoggerFactory; 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; @@ -126,6 +128,21 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface { 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 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; } 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 e644b13dc9..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 @@ -46,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; @@ -55,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 = ""; @@ -82,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; @@ -210,7 +213,8 @@ public class DetermineBasalAdapterSMBJS { MealData mealData, double autosensDataRatio, boolean tempTargetSet, - boolean microBolusAllowed + boolean microBolusAllowed, + boolean smbAlwaysAllowed ) throws JSONException { String units = profile.getUnits(); @@ -244,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 = MainApp.getConstraintChecker().isSMBModeEnabled().value() && MainApp.getConstraintChecker().isClosedLoopAllowed().value(); - 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); @@ -308,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/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java index c0b57a80d4..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 @@ -231,6 +231,15 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { } 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); @@ -239,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()); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bbe6036922..0efee647f8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -991,5 +991,7 @@ openapsama_useautosens Record pump site change Record insulin cartridge change + SMB always and after carbs disabled because active BG source doesn\'t support advanced filtering + SMB not allowed in open loop mode diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index a39fd4595e..24dda3a14e 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -13,6 +13,7 @@ import java.util.Locale; 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.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.utils.SP; @@ -56,6 +57,9 @@ public class AAPSMocker { when(MainApp.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable"); when(MainApp.gs(R.string.loop)).thenReturn("Loop"); when(MainApp.gs(R.string.loop_shortname)).thenReturn("LOOP"); + when(MainApp.gs(R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering"); + when(MainApp.gs(R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode"); + when(MainApp.gs(R.string.Glimp)).thenReturn("Glimp"); } public static MainApp mockMainApp() { @@ -71,6 +75,11 @@ public class AAPSMocker { when(MainApp.getConfigBuilder()).thenReturn(configBuilderPlugin); } + public static void mockConstraintsChecker() { + ConstraintChecker constraintChecker = mock(ConstraintChecker.class); + when(MainApp.getConstraintChecker()).thenReturn(constraintChecker); + } + public static void mockBus() { Bus bus = PowerMockito.mock(Bus.class); when(MainApp.bus()).thenReturn(bus); diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java index 46b8bb7a53..dd2459d9d7 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java @@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; import info.nightscout.androidaps.plugins.PumpInsight.connector.StatusTaskRunner; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; +import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; @@ -110,10 +111,21 @@ public class ConstraintsCheckerTest { Assert.assertEquals(Boolean.FALSE, c.value()); } + @Test + public void isAdvancedFilteringEnabledTest() throws Exception { + when(MainApp.getConfigBuilder().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin()); + + Constraint c = constraintChecker.isAdvancedFilteringEnabled(); + Assert.assertEquals(true, c.getReasonList().size() == 1); // Safety + Assert.assertEquals(true, c.getMostLimitedReasonList().size() == 1); // Safety + Assert.assertEquals(Boolean.FALSE, c.value()); + } + @Test public void isSMBModeEnabledTest() throws Exception { objectivesPlugin.objectives.get(7).setStarted(new Date(0)); when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false); + when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true)); Constraint c = constraintChecker.isSMBModeEnabled(); Assert.assertEquals(true, c.getReasonList().size() == 2); // Safety & Objectives @@ -240,6 +252,7 @@ public class ConstraintsCheckerTest { MainApp mainApp = AAPSMocker.mockMainApp(); AAPSMocker.mockConfigBuilder(); + AAPSMocker.mockConstraintsChecker(); AAPSMocker.mockApplicationContext(); AAPSMocker.mockBus(); AAPSMocker.mockStrings(); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPluginTest.java index 4b45734b2a..2ae35de4ae 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPluginTest.java @@ -21,6 +21,7 @@ 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.PumpVirtual.VirtualPumpPlugin; +import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin; import info.nightscout.utils.SP; import static org.mockito.Mockito.when; @@ -70,6 +71,7 @@ public class SafetyPluginTest { @Test public void notEnabledSMBInPreferencesDisablesSMB() throws Exception { when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false); + when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true)); Constraint c = new Constraint<>(true); c = safetyPlugin.isSMBModeEnabled(c); @@ -77,6 +79,27 @@ public class SafetyPluginTest { Assert.assertEquals(Boolean.FALSE, c.value()); } + @Test + public void openLoopPreventsSMB() throws Exception { + when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(true); + when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(false)); + + Constraint c = new Constraint<>(true); + c = safetyPlugin.isSMBModeEnabled(c); + Assert.assertEquals(true, c.getReasons().contains("SMB not allowed in open loop mode")); + Assert.assertEquals(Boolean.FALSE, c.value()); + } + + @Test + public void bgsourceShouldPreventSMBAlways() throws Exception { + when(MainApp.getConfigBuilder().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin()); + + Constraint c = new Constraint<>(true); + c = safetyPlugin.isAdvancedFilteringEnabled(c); + Assert.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons()); + Assert.assertEquals(Boolean.FALSE, c.value()); + } + @Test public void basalRateShouldBeLimited() throws Exception { when(SP.getDouble(R.string.key_openapsma_max_basal, 1d)).thenReturn(1d); @@ -204,9 +227,12 @@ public class SafetyPluginTest { public void prepareMock() { AAPSMocker.mockMainApp(); AAPSMocker.mockConfigBuilder(); + AAPSMocker.mockConstraintsChecker(); AAPSMocker.mockSP(); AAPSMocker.mockStrings(); + + when(MainApp.getConfigBuilder().getActivePump()).thenReturn(pump); safetyPlugin = SafetyPlugin.getPlugin();