LoopPlugin injection

This commit is contained in:
Milos Kozak 2019-12-30 11:35:49 +01:00
parent 270c1c69f4
commit 295ce489bf
13 changed files with 548 additions and 510 deletions

View file

@ -50,7 +50,7 @@ import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt; import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
@ -61,23 +61,24 @@ import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.PasswordProtection; import info.nightscout.androidaps.utils.PasswordProtection;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
public class MainActivity extends NoSplashAppCompatActivity { public class MainActivity extends NoSplashAppCompatActivity {
private CompositeDisposable disposable = new CompositeDisposable(); private CompositeDisposable disposable = new CompositeDisposable();
private ActionBarDrawerToggle actionBarDrawerToggle; private ActionBarDrawerToggle actionBarDrawerToggle;
private MenuItem pluginPreferencesMenuItem; private MenuItem pluginPreferencesMenuItem;
@Inject @Inject AAPSLogger aapsLogger;
SmsCommunicatorPlugin smsCommunicatorPlugin; @Inject RxBusWrapper rxBus;
@Inject SP sp;
@Inject ResourceHelper resourceHelper;
@Inject SmsCommunicatorPlugin smsCommunicatorPlugin;
@Inject LoopPlugin loopPlugin;
@Inject
AAPSLogger aapsLogger;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -118,7 +119,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
}); });
//Check here if loop plugin is disabled. Else check via constraints //Check here if loop plugin is disabled. Else check via constraints
if (!LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) if (!loopPlugin.isEnabled(PluginType.LOOP))
VersionCheckerUtilsKt.triggerCheckVersion(); VersionCheckerUtilsKt.triggerCheckVersion();
FabricPrivacy.setUserStats(); FabricPrivacy.setUserStats();
@ -126,7 +127,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
setupTabs(); setupTabs();
setupViews(); setupViews();
disposable.add(RxBus.Companion.getINSTANCE() disposable.add(rxBus
.toObservable(EventRebuildTabs.class) .toObservable(EventRebuildTabs.class)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> { .subscribe(event -> {
@ -140,13 +141,13 @@ public class MainActivity extends NoSplashAppCompatActivity {
setWakeLock(); setWakeLock();
}, FabricPrivacy::logException) }, FabricPrivacy::logException)
); );
disposable.add(RxBus.Companion.getINSTANCE() disposable.add(rxBus
.toObservable(EventPreferenceChange.class) .toObservable(EventPreferenceChange.class)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(this::processPreferenceChange, FabricPrivacy::logException) .subscribe(this::processPreferenceChange, FabricPrivacy::logException)
); );
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) { if (!sp.getBoolean(R.string.key_setupwizard_processed, false)) {
Intent intent = new Intent(this, SetupWizardActivity.class); Intent intent = new Intent(this, SetupWizardActivity.class);
startActivity(intent); startActivity(intent);
} }
@ -179,7 +180,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
} }
private void setWakeLock() { private void setWakeLock() {
boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false); boolean keepScreenOn = sp.getBoolean(R.string.key_keep_screen_on, false);
if (keepScreenOn) if (keepScreenOn)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
else else
@ -225,7 +226,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
TabLayout compactTabs = findViewById(R.id.tabs_compact); TabLayout compactTabs = findViewById(R.id.tabs_compact);
compactTabs.setupWithViewPager(viewPager, true); compactTabs.setupWithViewPager(viewPager, true);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
if (SP.getBoolean("short_tabtitles", false)) { if (sp.getBoolean("short_tabtitles", false)) {
normalTabs.setVisibility(View.GONE); normalTabs.setVisibility(View.GONE);
compactTabs.setVisibility(View.VISIBLE); compactTabs.setVisibility(View.VISIBLE);
toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.compact_height))); toolbar.setLayoutParams(new LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.compact_height)));
@ -248,7 +249,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
switch (requestCode) { switch (requestCode) {
case AndroidPermission.CASE_STORAGE: case AndroidPermission.CASE_STORAGE:
//show dialog after permission is granted //show dialog after permission is granted
OKDialog.show(this, "", MainApp.gs(R.string.alert_dialog_storage_permission_text)); OKDialog.show(this, "", resourceHelper.gs(R.string.alert_dialog_storage_permission_text));
break; break;
case AndroidPermission.CASE_LOCATION: case AndroidPermission.CASE_LOCATION:
case AndroidPermission.CASE_SMS: case AndroidPermission.CASE_SMS:
@ -304,25 +305,25 @@ public class MainActivity extends NoSplashAppCompatActivity {
return true; return true;
case R.id.nav_about: case R.id.nav_about:
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(MainApp.gs(R.string.app_name) + " " + BuildConfig.VERSION); builder.setTitle(resourceHelper.gs(R.string.app_name) + " " + BuildConfig.VERSION);
builder.setIcon(MainApp.getIcon()); builder.setIcon(MainApp.getIcon());
String message = "Build: " + BuildConfig.BUILDVERSION + "\n"; String message = "Build: " + BuildConfig.BUILDVERSION + "\n";
message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n"; message += "Flavor: " + BuildConfig.FLAVOR + BuildConfig.BUILD_TYPE + "\n";
message += MainApp.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName; message += resourceHelper.gs(R.string.configbuilder_nightscoutversion_label) + " " + NSSettingsStatus.getInstance().nightscoutVersionName;
if (MainApp.engineeringMode) if (MainApp.engineeringMode)
message += "\n" + MainApp.gs(R.string.engineering_mode_enabled); message += "\n" + resourceHelper.gs(R.string.engineering_mode_enabled);
message += MainApp.gs(R.string.about_link_urls); message += resourceHelper.gs(R.string.about_link_urls);
final SpannableString messageSpanned = new SpannableString(message); final SpannableString messageSpanned = new SpannableString(message);
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS); Linkify.addLinks(messageSpanned, Linkify.WEB_URLS);
builder.setMessage(messageSpanned); builder.setMessage(messageSpanned);
builder.setPositiveButton(MainApp.gs(R.string.ok), null); builder.setPositiveButton(resourceHelper.gs(R.string.ok), null);
AlertDialog alertDialog = builder.create(); AlertDialog alertDialog = builder.create();
alertDialog.show(); alertDialog.show();
((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); ((TextView) alertDialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
return true; return true;
case R.id.nav_exit: case R.id.nav_exit:
aapsLogger.debug(LTag.CORE, "Exiting"); aapsLogger.debug(LTag.CORE, "Exiting");
RxBus.Companion.getINSTANCE().send(new EventAppExit()); rxBus.send(new EventAppExit());
finish(); finish();
System.runFinalization(); System.runFinalization();
System.exit(0); System.exit(0);

View file

@ -139,6 +139,7 @@ public class MainApp extends DaggerApplication {
@Inject InsulinOrefRapidActingPlugin insulinOrefRapidActingPlugin; @Inject InsulinOrefRapidActingPlugin insulinOrefRapidActingPlugin;
@Inject InsulinOrefUltraRapidActingPlugin insulinOrefUltraRapidActingPlugin; @Inject InsulinOrefUltraRapidActingPlugin insulinOrefUltraRapidActingPlugin;
@Inject LocalProfilePlugin localProfilePlugin; @Inject LocalProfilePlugin localProfilePlugin;
@Inject LoopPlugin loopPlugin;
@Inject ObjectivesPlugin objectivesPlugin; @Inject ObjectivesPlugin objectivesPlugin;
@Inject SafetyPlugin safetyPlugin; @Inject SafetyPlugin safetyPlugin;
@Inject SmsCommunicatorPlugin smsCommunicatorPlugin; @Inject SmsCommunicatorPlugin smsCommunicatorPlugin;
@ -225,7 +226,7 @@ public class MainApp extends DaggerApplication {
if (!Config.NSCLIENT) pluginsList.add(MDIPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(MDIPlugin.getPlugin());
pluginsList.add(virtualPumpPlugin); pluginsList.add(virtualPumpPlugin);
pluginsList.add(careportalPlugin); pluginsList.add(careportalPlugin);
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin()); if (Config.APS) pluginsList.add(loopPlugin);
if (Config.APS) pluginsList.add(openAPSMAPlugin); if (Config.APS) pluginsList.add(openAPSMAPlugin);
if (Config.APS) pluginsList.add(openAPSAMAPlugin); if (Config.APS) pluginsList.add(openAPSAMAPlugin);
if (Config.APS) pluginsList.add(openAPSSMBPlugin); if (Config.APS) pluginsList.add(openAPSSMBPlugin);

View file

@ -56,6 +56,7 @@ public class MyPreferenceFragment extends PreferenceFragment implements HasAndro
@Inject DanaRSPlugin danaRSPlugin; @Inject DanaRSPlugin danaRSPlugin;
@Inject CareportalPlugin careportalPlugin; @Inject CareportalPlugin careportalPlugin;
@Inject InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin; @Inject InsulinOrefFreePeakPlugin insulinOrefFreePeakPlugin;
@Inject LoopPlugin loopPlugin;
@Inject OpenAPSAMAPlugin openAPSAMAPlugin; @Inject OpenAPSAMAPlugin openAPSAMAPlugin;
@Inject OpenAPSMAPlugin openAPSMAPlugin; @Inject OpenAPSMAPlugin openAPSMAPlugin;
@Inject OpenAPSSMBPlugin openAPSSMBPlugin; @Inject OpenAPSSMBPlugin openAPSSMBPlugin;
@ -108,7 +109,7 @@ public class MyPreferenceFragment extends PreferenceFragment implements HasAndro
addPreferencesFromResourceIfEnabled(careportalPlugin, PluginType.GENERAL); addPreferencesFromResourceIfEnabled(careportalPlugin, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(safetyPlugin, PluginType.CONSTRAINTS); addPreferencesFromResourceIfEnabled(safetyPlugin, PluginType.CONSTRAINTS);
if (Config.APS) { if (Config.APS) {
addPreferencesFromResourceIfEnabled(LoopPlugin.getPlugin(), PluginType.LOOP); addPreferencesFromResourceIfEnabled(loopPlugin, PluginType.LOOP);
addPreferencesFromResourceIfEnabled(openAPSMAPlugin, PluginType.APS); addPreferencesFromResourceIfEnabled(openAPSMAPlugin, PluginType.APS);
addPreferencesFromResourceIfEnabled(openAPSAMAPlugin, PluginType.APS); addPreferencesFromResourceIfEnabled(openAPSAMAPlugin, PluginType.APS);
addPreferencesFromResourceIfEnabled(openAPSSMBPlugin, PluginType.APS); addPreferencesFromResourceIfEnabled(openAPSSMBPlugin, PluginType.APS);

View file

@ -4,6 +4,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.activities.MyPreferenceFragment import info.nightscout.androidaps.activities.MyPreferenceFragment
import info.nightscout.androidaps.dialogs.* import info.nightscout.androidaps.dialogs.*
import info.nightscout.androidaps.plugins.aps.loop.LoopFragment
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAFragment import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAFragment
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAFragment import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAFragment
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBFragment import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBFragment
@ -56,6 +57,7 @@ abstract class FragmentsModule {
@ContributesAndroidInjector abstract fun contributesOpenAPSMAFragment(): OpenAPSMAFragment @ContributesAndroidInjector abstract fun contributesOpenAPSMAFragment(): OpenAPSMAFragment
@ContributesAndroidInjector abstract fun contributesOpenAPSSMBFragment(): OpenAPSSMBFragment @ContributesAndroidInjector abstract fun contributesOpenAPSSMBFragment(): OpenAPSSMBFragment
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment @ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
@ContributesAndroidInjector abstract fun contributesMedtronicFragment(): MedtronicFragment @ContributesAndroidInjector abstract fun contributesMedtronicFragment(): MedtronicFragment
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment @ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment @ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment

View file

@ -1,23 +1,31 @@
package info.nightscout.androidaps.plugins.aps.loop package info.nightscout.androidaps.plugins.aps.loop
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.loop_fragment.* import kotlinx.android.synthetic.main.loop_fragment.*
import javax.inject.Inject
class LoopFragment : Fragment() { class LoopFragment : DaggerFragment() {
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var loopPlugin: LoopPlugin
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
@ -30,35 +38,35 @@ class LoopFragment : Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
loop_run.setOnClickListener { loop_run.setOnClickListener {
loop_lastrun.text = MainApp.gs(R.string.executing) loop_lastrun.text = resourceHelper.gs(R.string.executing)
Thread { LoopPlugin.getPlugin().invoke("Loop button", true) }.start() Thread { loopPlugin.invoke("Loop button", true) }.start()
} }
} }
@Synchronized @Synchronized
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
disposable += RxBus.INSTANCE disposable += rxBus
.toObservable(EventLoopUpdateGui::class.java) .toObservable(EventLoopUpdateGui::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
updateGUI() updateGUI()
}, { }, {
FabricPrivacy.logException(it) FabricPrivacy.logException(it)
}) })
disposable += RxBus.INSTANCE disposable += rxBus
.toObservable(EventLoopSetLastRunGui::class.java) .toObservable(EventLoopSetLastRunGui::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
clearGUI() clearGUI()
loop_lastrun.text = it.text loop_lastrun.text = it.text
}, { }, {
FabricPrivacy.logException(it) FabricPrivacy.logException(it)
}) })
updateGUI() updateGUI()
SP.putBoolean(R.string.key_objectiveuseloop, true) sp.putBoolean(R.string.key_objectiveuseloop, true)
} }
@Synchronized @Synchronized
@ -75,21 +83,21 @@ class LoopFragment : Fragment() {
loop_constraintsprocessed.text = it.constraintsProcessed?.toSpanned() ?: "" loop_constraintsprocessed.text = it.constraintsProcessed?.toSpanned() ?: ""
loop_source.text = it.source ?: "" loop_source.text = it.source ?: ""
loop_lastrun.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) } loop_lastrun.text = it.lastAPSRun?.let { lastRun -> DateUtil.dateAndTimeString(lastRun.time) }
?: "" ?: ""
loop_lastenact.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) } loop_lastenact.text = it.lastAPSRun?.let { lastEnact -> DateUtil.dateAndTimeString(lastEnact.time) }
?: "" ?: ""
loop_tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) } loop_tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
?: "" ?: ""
loop_smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) } loop_smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
?: "" ?: ""
val constraints = val constraints =
it.constraintsProcessed?.let { constraintsProcessed -> it.constraintsProcessed?.let { constraintsProcessed ->
val allConstraints = Constraint(0.0) val allConstraints = Constraint(0.0)
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) } constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) } constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
allConstraints.mostLimitedReasons allConstraints.mostLimitedReasons
} ?: "" } ?: ""
loop_constraints.text = constraints loop_constraints.text = constraints
} }
} }

View file

@ -14,17 +14,16 @@ import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date; import java.util.Date;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
@ -43,17 +42,17 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpDescription;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui; import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui;
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui; import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui;
import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification; import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification;
import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker; import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
@ -61,16 +60,25 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.androidaps.queue.commands.Command;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
/** @Singleton
* Created by mike on 05.08.2016.
*/
public class LoopPlugin extends PluginBase { public class LoopPlugin extends PluginBase {
private static Logger log = LoggerFactory.getLogger(L.APS); private final AAPSLogger aapsLogger;
private final RxBusWrapper rxBus;
private final SP sp;
private final ConstraintChecker constraintChecker;
private final ResourceHelper resourceHelper;
private final ProfileFunction profileFunction;
private final MainApp mainApp;
private final ConfigBuilderPlugin configBuilderPlugin;
private final TreatmentsPlugin treatmentsPlugin;
private final VirtualPumpPlugin virtualPumpPlugin;
private CompositeDisposable disposable = new CompositeDisposable(); private CompositeDisposable disposable = new CompositeDisposable();
private static final String CHANNEL_ID = "AndroidAPS-Openloop"; private static final String CHANNEL_ID = "AndroidAPS-Openloop";
@ -83,14 +91,14 @@ public class LoopPlugin extends PluginBase {
@Deprecated @Deprecated
public static LoopPlugin getPlugin() { public static LoopPlugin getPlugin() {
if (loopPlugin == null) { if (loopPlugin == null) {
loopPlugin = new LoopPlugin(); throw new IllegalStateException("Accessing LoopPlugin before first instantiation");
} }
return loopPlugin; return loopPlugin;
} }
private long loopSuspendedTill = 0L; // end of manual loop suspend private long loopSuspendedTill; // end of manual loop suspend
private boolean isSuperBolus = false; private boolean isSuperBolus;
private boolean isDisconnected = false; private boolean isDisconnected;
public class LastRun { public class LastRun {
public APSResult request = null; public APSResult request = null;
@ -105,7 +113,19 @@ public class LoopPlugin extends PluginBase {
static public LastRun lastRun = null; static public LastRun lastRun = null;
public LoopPlugin() { @Inject
public LoopPlugin(
AAPSLogger aapsLogger,
RxBusWrapper rxBus,
SP sp,
ConstraintChecker constraintChecker,
ResourceHelper resourceHelper,
ProfileFunction profileFunction,
MainApp mainApp,
ConfigBuilderPlugin configBuilderPlugin,
TreatmentsPlugin treatmentsPlugin,
VirtualPumpPlugin virtualPumpPlugin
) {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.LOOP) .mainType(PluginType.LOOP)
.fragmentClass(LoopFragment.class.getName()) .fragmentClass(LoopFragment.class.getName())
@ -114,21 +134,31 @@ public class LoopPlugin extends PluginBase {
.preferencesId(R.xml.pref_loop) .preferencesId(R.xml.pref_loop)
.description(R.string.description_loop) .description(R.string.description_loop)
); );
loopSuspendedTill = SP.getLong("loopSuspendedTill", 0L); this.loopPlugin = this; //TODO remove
isSuperBolus = SP.getBoolean("isSuperBolus", false); this.aapsLogger = aapsLogger;
isDisconnected = SP.getBoolean("isDisconnected", false); this.rxBus = rxBus;
this.sp = sp;
this.constraintChecker = constraintChecker;
this.resourceHelper = resourceHelper;
this.profileFunction = profileFunction;
this.mainApp = mainApp;
this.configBuilderPlugin = configBuilderPlugin;
this.treatmentsPlugin = treatmentsPlugin;
this.virtualPumpPlugin = virtualPumpPlugin;
loopSuspendedTill = sp.getLong("loopSuspendedTill", 0L);
isSuperBolus = sp.getBoolean("isSuperBolus", false);
isDisconnected = sp.getBoolean("isDisconnected", false);
} }
@Override @Override
protected void onStart() { protected void onStart() {
createNotificationChannel(); createNotificationChannel();
super.onStart(); super.onStart();
disposable.add(RxBus.Companion.getINSTANCE() disposable.add(rxBus
.toObservable(EventTempTargetChange.class) .toObservable(EventTempTargetChange.class)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe(event -> { .subscribe(event -> invoke("EventTempTargetChange", true), FabricPrivacy::logException)
invoke("EventTempTargetChange", true);
}, FabricPrivacy::logException)
); );
/** /**
* This method is triggered once autosens calculation has completed, so the LoopPlugin * This method is triggered once autosens calculation has completed, so the LoopPlugin
@ -137,7 +167,7 @@ public class LoopPlugin extends PluginBase {
* the event causing the calculation is not EventNewBg. * the event causing the calculation is not EventNewBg.
* <p> * <p>
*/ */
disposable.add(RxBus.Companion.getINSTANCE() disposable.add(rxBus
.toObservable(EventAutosensCalculationFinished.class) .toObservable(EventAutosensCalculationFinished.class)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe(event -> { .subscribe(event -> {
@ -160,7 +190,7 @@ public class LoopPlugin extends PluginBase {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = NotificationManager mNotificationManager =
(NotificationManager) MainApp.instance().getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) mainApp.getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel(CHANNEL_ID, @SuppressLint("WrongConstant") NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
CHANNEL_ID, CHANNEL_ID,
NotificationManager.IMPORTANCE_HIGH); NotificationManager.IMPORTANCE_HIGH);
@ -176,7 +206,7 @@ public class LoopPlugin extends PluginBase {
@Override @Override
public boolean specialEnableCondition() { public boolean specialEnableCondition() {
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface pump = configBuilderPlugin.getActivePump();
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
@ -188,27 +218,27 @@ public class LoopPlugin extends PluginBase {
loopSuspendedTill = endTime; loopSuspendedTill = endTime;
isSuperBolus = false; isSuperBolus = false;
isDisconnected = false; isDisconnected = false;
SP.putLong("loopSuspendedTill", loopSuspendedTill); sp.putLong("loopSuspendedTill", loopSuspendedTill);
SP.putBoolean("isSuperBolus", isSuperBolus); sp.putBoolean("isSuperBolus", isSuperBolus);
SP.putBoolean("isDisconnected", isDisconnected); sp.putBoolean("isDisconnected", isDisconnected);
} }
public void superBolusTo(long endTime) { public void superBolusTo(long endTime) {
loopSuspendedTill = endTime; loopSuspendedTill = endTime;
isSuperBolus = true; isSuperBolus = true;
isDisconnected = false; isDisconnected = false;
SP.putLong("loopSuspendedTill", loopSuspendedTill); sp.putLong("loopSuspendedTill", loopSuspendedTill);
SP.putBoolean("isSuperBolus", isSuperBolus); sp.putBoolean("isSuperBolus", isSuperBolus);
SP.putBoolean("isDisconnected", isDisconnected); sp.putBoolean("isDisconnected", isDisconnected);
} }
public void disconnectTo(long endTime) { private void disconnectTo(long endTime) {
loopSuspendedTill = endTime; loopSuspendedTill = endTime;
isSuperBolus = false; isSuperBolus = false;
isDisconnected = true; isDisconnected = true;
SP.putLong("loopSuspendedTill", loopSuspendedTill); sp.putLong("loopSuspendedTill", loopSuspendedTill);
SP.putBoolean("isSuperBolus", isSuperBolus); sp.putBoolean("isSuperBolus", isSuperBolus);
SP.putBoolean("isDisconnected", isDisconnected); sp.putBoolean("isDisconnected", isDisconnected);
} }
public int minutesToEndOfSuspend() { public int minutesToEndOfSuspend() {
@ -273,36 +303,36 @@ public class LoopPlugin extends PluginBase {
public synchronized void invoke(String initiator, boolean allowNotification, boolean tempBasalFallback) { public synchronized void invoke(String initiator, boolean allowNotification, boolean tempBasalFallback) {
try { try {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "invoke from " + initiator);
log.debug("invoke from " + initiator); Constraint<Boolean> loopEnabled = constraintChecker.isLoopInvocationAllowed();
Constraint<Boolean> loopEnabled = ConstraintChecker.getInstance().isLoopInvocationAllowed();
if (!loopEnabled.value()) { if (!loopEnabled.value()) {
String message = MainApp.gs(R.string.loopdisabled) + "\n" + loopEnabled.getReasons(); String message = resourceHelper.gs(R.string.loopdisabled) + "\n" + loopEnabled.getReasons();
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, message);
log.debug(message); rxBus.send(new EventLoopSetLastRunGui(message));
RxBus.Companion.getINSTANCE().send(new EventLoopSetLastRunGui(message));
return; return;
} }
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); final PumpInterface pump = configBuilderPlugin.getActivePump();
if (pump == null)
return;
APSResult result = null; APSResult result = null;
if (!isEnabled(PluginType.LOOP)) if (!isEnabled(PluginType.LOOP))
return; return;
Profile profile = ProfileFunctions.getInstance().getProfile(); Profile profile = profileFunction.getProfile();
if (profile == null || !ProfileFunctions.getInstance().isProfileValid("Loop")) { if (profile == null || !profileFunction.isProfileValid("Loop")) {
if (L.isEnabled(L.APS)) if (L.isEnabled(L.APS))
log.debug(MainApp.gs(R.string.noprofileselected)); aapsLogger.debug(LTag.APS, resourceHelper.gs(R.string.noprofileselected));
RxBus.Companion.getINSTANCE().send(new EventLoopSetLastRunGui(MainApp.gs(R.string.noprofileselected))); rxBus.send(new EventLoopSetLastRunGui(resourceHelper.gs(R.string.noprofileselected)));
return; return;
} }
// Check if pump info is loaded // Check if pump info is loaded
if (pump.getBaseBasalRate() < 0.01d) return; if (pump.getBaseBasalRate() < 0.01d) return;
APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS(); APSInterface usedAPS = configBuilderPlugin.getActiveAPS();
if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) { if (usedAPS != null && ((PluginBase) usedAPS).isEnabled(PluginType.APS)) {
usedAPS.invoke(initiator, tempBasalFallback); usedAPS.invoke(initiator, tempBasalFallback);
result = usedAPS.getLastAPSResult(); result = usedAPS.getLastAPSResult();
@ -310,7 +340,7 @@ public class LoopPlugin extends PluginBase {
// Check if we have any result // Check if we have any result
if (result == null) { if (result == null) {
RxBus.Companion.getINSTANCE().send(new EventLoopSetLastRunGui(MainApp.gs(R.string.noapsselected))); rxBus.send(new EventLoopSetLastRunGui(resourceHelper.gs(R.string.noapsselected)));
return; return;
} }
@ -323,19 +353,18 @@ public class LoopPlugin extends PluginBase {
// check rate for constrais // check rate for constrais
final APSResult resultAfterConstraints = result.clone(); final APSResult resultAfterConstraints = result.clone();
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate); resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
resultAfterConstraints.rate = ConstraintChecker.getInstance().applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value(); resultAfterConstraints.rate = constraintChecker.applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value();
resultAfterConstraints.percentConstraint = new Constraint<>(resultAfterConstraints.percent); resultAfterConstraints.percentConstraint = new Constraint<>(resultAfterConstraints.percent);
resultAfterConstraints.percent = ConstraintChecker.getInstance().applyBasalPercentConstraints(resultAfterConstraints.percentConstraint, profile).value(); resultAfterConstraints.percent = constraintChecker.applyBasalPercentConstraints(resultAfterConstraints.percentConstraint, profile).value();
resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb); resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb);
resultAfterConstraints.smb = ConstraintChecker.getInstance().applyBolusConstraints(resultAfterConstraints.smbConstraint).value(); resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint).value();
// safety check for multiple SMBs // safety check for multiple SMBs
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime(); long lastBolusTime = treatmentsPlugin.getLastBolusTime();
if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) { if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "SMB requsted but still in 3 min interval");
log.debug("SMB requsted but still in 3 min interval");
resultAfterConstraints.smb = 0; resultAfterConstraints.smb = 0;
} }
@ -350,32 +379,30 @@ public class LoopPlugin extends PluginBase {
NSUpload.uploadDeviceStatus(); NSUpload.uploadDeviceStatus();
if (isSuspended()) { if (isSuspended()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, resourceHelper.gs(R.string.loopsuspended));
log.debug(MainApp.gs(R.string.loopsuspended)); rxBus.send(new EventLoopSetLastRunGui(resourceHelper.gs(R.string.loopsuspended)));
RxBus.Companion.getINSTANCE().send(new EventLoopSetLastRunGui(MainApp.gs(R.string.loopsuspended)));
return; return;
} }
if (pump.isSuspended()) { if (pump.isSuspended()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, resourceHelper.gs(R.string.pumpsuspended));
log.debug(MainApp.gs(R.string.pumpsuspended)); rxBus.send(new EventLoopSetLastRunGui(resourceHelper.gs(R.string.pumpsuspended)));
RxBus.Companion.getINSTANCE().send(new EventLoopSetLastRunGui(MainApp.gs(R.string.pumpsuspended)));
return; return;
} }
Constraint<Boolean> closedLoopEnabled = ConstraintChecker.getInstance().isClosedLoopAllowed(); Constraint<Boolean> closedLoopEnabled = constraintChecker.isClosedLoopAllowed();
if (closedLoopEnabled.value()) { if (closedLoopEnabled.value()) {
if (resultAfterConstraints.isChangeRequested() if (resultAfterConstraints.isChangeRequested()
&& !ConfigBuilderPlugin.getPlugin().getCommandQueue().bolusInQueue() && !configBuilderPlugin.getCommandQueue().bolusInQueue()
&& !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BOLUS)) { && !configBuilderPlugin.getCommandQueue().isRunning(Command.CommandType.BOLUS)) {
final PumpEnactResult waiting = new PumpEnactResult(); final PumpEnactResult waiting = new PumpEnactResult();
waiting.queued = true; waiting.queued = true;
if (resultAfterConstraints.tempBasalRequested) if (resultAfterConstraints.tempBasalRequested)
lastRun.tbrSetByPump = waiting; lastRun.tbrSetByPump = waiting;
if (resultAfterConstraints.bolusRequested) if (resultAfterConstraints.bolusRequested)
lastRun.smbSetByPump = waiting; lastRun.smbSetByPump = waiting;
RxBus.Companion.getINSTANCE().send(new EventLoopUpdateGui()); rxBus.send(new EventLoopUpdateGui());
FabricPrivacy.getInstance().logCustom("APSRequest"); FabricPrivacy.getInstance().logCustom("APSRequest");
applyTBRRequest(resultAfterConstraints, profile, new Callback() { applyTBRRequest(resultAfterConstraints, profile, new Callback() {
@Override @Override
@ -393,14 +420,14 @@ public class LoopPlugin extends PluginBase {
} else { } else {
new Thread(() -> { new Thread(() -> {
SystemClock.sleep(1000); SystemClock.sleep(1000);
LoopPlugin.getPlugin().invoke("tempBasalFallback", allowNotification, true); invoke("tempBasalFallback", allowNotification, true);
}).start(); }).start();
} }
RxBus.Companion.getINSTANCE().send(new EventLoopUpdateGui()); rxBus.send(new EventLoopUpdateGui());
} }
}); });
} }
RxBus.Companion.getINSTANCE().send(new EventLoopUpdateGui()); rxBus.send(new EventLoopUpdateGui());
} }
}); });
} else { } else {
@ -410,26 +437,26 @@ public class LoopPlugin extends PluginBase {
} else { } else {
if (resultAfterConstraints.isChangeRequested() && allowNotification) { if (resultAfterConstraints.isChangeRequested() && allowNotification) {
NotificationCompat.Builder builder = NotificationCompat.Builder builder =
new NotificationCompat.Builder(MainApp.instance().getApplicationContext(), CHANNEL_ID); new NotificationCompat.Builder(mainApp, CHANNEL_ID);
builder.setSmallIcon(R.drawable.notif_icon) builder.setSmallIcon(R.drawable.notif_icon)
.setContentTitle(MainApp.gs(R.string.openloop_newsuggestion)) .setContentTitle(resourceHelper.gs(R.string.openloop_newsuggestion))
.setContentText(resultAfterConstraints.toString()) .setContentText(resultAfterConstraints.toString())
.setAutoCancel(true) .setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH) .setPriority(Notification.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_ALARM) .setCategory(Notification.CATEGORY_ALARM)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
if (SP.getBoolean("wearcontrol", false)) { if (sp.getBoolean("wearcontrol", false)) {
builder.setLocalOnly(true); builder.setLocalOnly(true);
} }
// Creates an explicit intent for an Activity in your app // Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class); Intent resultIntent = new Intent(mainApp, MainActivity.class);
// The stack builder object will contain an artificial back stack for the // The stack builder object will contain an artificial back stack for the
// started Activity. // started Activity.
// This ensures that navigating backward from the Activity leads out of // This ensures that navigating backward from the Activity leads out of
// your application to the Home screen. // your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(MainApp.instance().getApplicationContext()); TaskStackBuilder stackBuilder = TaskStackBuilder.create(mainApp);
stackBuilder.addParentStack(MainActivity.class); stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack // Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent); stackBuilder.addNextIntent(resultIntent);
@ -438,31 +465,30 @@ public class LoopPlugin extends PluginBase {
builder.setContentIntent(resultPendingIntent); builder.setContentIntent(resultPendingIntent);
builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000}); builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
NotificationManager mNotificationManager = NotificationManager mNotificationManager =
(NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) mainApp.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on. // mId allows you to update the notification later on.
mNotificationManager.notify(Constants.notificationID, builder.build()); mNotificationManager.notify(Constants.notificationID, builder.build());
RxBus.Companion.getINSTANCE().send(new EventNewOpenLoopNotification()); rxBus.send(new EventNewOpenLoopNotification());
// Send to Wear // Send to Wear
ActionStringHandler.handleInitiate("changeRequest"); ActionStringHandler.handleInitiate("changeRequest");
} else if (allowNotification) { } else if (allowNotification) {
// dismiss notifications // dismiss notifications
NotificationManager notificationManager = NotificationManager notificationManager =
(NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) mainApp.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(Constants.notificationID); notificationManager.cancel(Constants.notificationID);
ActionStringHandler.handleInitiate("cancelChangeRequest"); ActionStringHandler.handleInitiate("cancelChangeRequest");
} }
} }
RxBus.Companion.getINSTANCE().send(new EventLoopUpdateGui()); rxBus.send(new EventLoopUpdateGui());
} finally { } finally {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "invoke end");
log.debug("invoke end");
} }
} }
public void acceptChangeRequest() { public void acceptChangeRequest() {
Profile profile = ProfileFunctions.getInstance().getProfile(); Profile profile = profileFunction.getProfile();
applyTBRRequest(lastRun.constraintsProcessed, profile, new Callback() { applyTBRRequest(lastRun.constraintsProcessed, profile, new Callback() {
@Override @Override
@ -472,9 +498,9 @@ public class LoopPlugin extends PluginBase {
lastRun.lastEnact = new Date(); lastRun.lastEnact = new Date();
lastRun.lastOpenModeAccept = new Date(); lastRun.lastOpenModeAccept = new Date();
NSUpload.uploadDeviceStatus(); NSUpload.uploadDeviceStatus();
SP.incInt(R.string.key_ObjectivesmanualEnacts); sp.incInt(R.string.key_ObjectivesmanualEnacts);
} }
RxBus.Companion.getINSTANCE().send(new EventAcceptOpenLoopChange()); rxBus.send(new EventAcceptOpenLoopChange());
} }
}); });
FabricPrivacy.getInstance().logCustom("AcceptTemp"); FabricPrivacy.getInstance().logCustom("AcceptTemp");
@ -485,206 +511,199 @@ public class LoopPlugin extends PluginBase {
* TODO: update pump drivers to support APS request in % * TODO: update pump drivers to support APS request in %
*/ */
public void applyTBRRequest(APSResult request, Profile profile, Callback callback) { private void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
boolean allowPercentage = VirtualPumpPlugin.Companion.getPlugin().isEnabled(PluginType.PUMP); boolean allowPercentage = virtualPumpPlugin.isEnabled(PluginType.PUMP);
if (!request.tempBasalRequested) { if (!request.tempBasalRequested) {
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().enacted(false).success(true).comment(MainApp.gs(R.string.nochangerequested))).run(); callback.result(new PumpEnactResult().enacted(false).success(true).comment(resourceHelper.gs(R.string.nochangerequested))).run();
} }
return; return;
} }
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface pump = configBuilderPlugin.getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); if (pump == null) {
if (callback != null)
callback.result(new PumpEnactResult().enacted(false).success(false).comment(resourceHelper.gs(R.string.nopumpselected))).run();
return;
}
if (!pump.isInitialized()) { if (!pump.isInitialized()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: " + resourceHelper.gs(R.string.pumpNotInitialized));
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpNotInitialized));
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run(); callback.result(new PumpEnactResult().comment(resourceHelper.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
} }
return; return;
} }
if (pump.isSuspended()) { if (pump.isSuspended()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: " + resourceHelper.gs(R.string.pumpsuspended));
log.debug("applyAPSRequest: " + MainApp.gs(R.string.pumpsuspended));
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run(); callback.result(new PumpEnactResult().comment(resourceHelper.gs(R.string.pumpsuspended)).enacted(false).success(false)).run();
} }
return; return;
} }
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: " + request.toString());
log.debug("applyAPSRequest: " + request.toString());
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
TemporaryBasal activeTemp = activeTreatments.getTempBasalFromHistory(now); TemporaryBasal activeTemp = treatmentsPlugin.getTempBasalFromHistory(now);
if (request.usePercent && allowPercentage) { if (request.usePercent && allowPercentage) {
if (request.percent == 100 && request.duration == 0) { if (request.percent == 100 && request.duration == 0) {
if (activeTemp != null) { if (activeTemp != null) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: cancelTempBasal()");
log.debug("applyAPSRequest: cancelTempBasal()"); configBuilderPlugin.getCommandQueue().cancelTempBasal(false, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(false, callback);
} else { } else {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly");
log.debug("applyAPSRequest: Basal set correctly");
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().percent(request.percent).duration(0) callback.result(new PumpEnactResult().percent(request.percent).duration(0)
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run(); .enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly))).run();
} }
} }
} else if (activeTemp != null } else if (activeTemp != null
&& activeTemp.getPlannedRemainingMinutes() > 5 && activeTemp.getPlannedRemainingMinutes() > 5
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30 && request.duration - activeTemp.getPlannedRemainingMinutes() < 30
&& request.percent == activeTemp.percentRate) { && request.percent == activeTemp.percentRate) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly");
log.debug("applyAPSRequest: Temp basal set correctly");
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().percent(request.percent) callback.result(new PumpEnactResult().percent(request.percent)
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes()) .enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
.comment(MainApp.gs(R.string.let_temp_basal_run))).run(); .comment(resourceHelper.gs(R.string.let_temp_basal_run))).run();
} }
} else { } else {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: tempBasalPercent()");
log.debug("applyAPSRequest: tempBasalPercent()"); configBuilderPlugin.getCommandQueue().tempBasalPercent(request.percent, request.duration, false, profile, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(request.percent, request.duration, false, profile, callback);
} }
} else { } else {
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) { if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
if (activeTemp != null) { if (activeTemp != null) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: cancelTempBasal()");
log.debug("applyAPSRequest: cancelTempBasal()"); configBuilderPlugin.getCommandQueue().cancelTempBasal(false, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(false, callback);
} else { } else {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: Basal set correctly");
log.debug("applyAPSRequest: Basal set correctly");
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().absolute(request.rate).duration(0) callback.result(new PumpEnactResult().absolute(request.rate).duration(0)
.enacted(false).success(true).comment(MainApp.gs(R.string.basal_set_correctly))).run(); .enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly))).run();
} }
} }
} else if (activeTemp != null } else if (activeTemp != null
&& activeTemp.getPlannedRemainingMinutes() > 5 && activeTemp.getPlannedRemainingMinutes() > 5
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30 && request.duration - activeTemp.getPlannedRemainingMinutes() < 30
&& Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) { && Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: Temp basal set correctly");
log.debug("applyAPSRequest: Temp basal set correctly");
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile)) callback.result(new PumpEnactResult().absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes()) .enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
.comment(MainApp.gs(R.string.let_temp_basal_run))).run(); .comment(resourceHelper.gs(R.string.let_temp_basal_run))).run();
} }
} else { } else {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()");
log.debug("applyAPSRequest: setTempBasalAbsolute()"); configBuilderPlugin.getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
} }
} }
} }
public void applySMBRequest(APSResult request, Callback callback) { private void applySMBRequest(APSResult request, Callback callback) {
if (!request.bolusRequested) { if (!request.bolusRequested) {
return; return;
} }
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface pump = configBuilderPlugin.getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); if (pump == null) {
if (callback != null)
callback.result(new PumpEnactResult().enacted(false).success(false).comment(resourceHelper.gs(R.string.nopumpselected))).run();
return;
}
long lastBolusTime = activeTreatments.getLastBolusTime(); long lastBolusTime = treatmentsPlugin.getLastBolusTime();
if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) { if (lastBolusTime != 0 && lastBolusTime + 3 * 60 * 1000 > System.currentTimeMillis()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "SMB requested but still in 3 min interval");
log.debug("SMB requested but still in 3 min interval");
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult() callback.result(new PumpEnactResult()
.comment(MainApp.gs(R.string.smb_frequency_exceeded)) .comment(resourceHelper.gs(R.string.smb_frequency_exceeded))
.enacted(false).success(false)).run(); .enacted(false).success(false)).run();
} }
return; return;
} }
if (!pump.isInitialized()) { if (!pump.isInitialized()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applySMBRequest: " + resourceHelper.gs(R.string.pumpNotInitialized));
log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpNotInitialized));
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run(); callback.result(new PumpEnactResult().comment(resourceHelper.gs(R.string.pumpNotInitialized)).enacted(false).success(false)).run();
} }
return; return;
} }
if (pump.isSuspended()) { if (pump.isSuspended()) {
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applySMBRequest: " + resourceHelper.gs(R.string.pumpsuspended));
log.debug("applySMBRequest: " + MainApp.gs(R.string.pumpsuspended));
if (callback != null) { if (callback != null) {
callback.result(new PumpEnactResult().comment(MainApp.gs(R.string.pumpsuspended)).enacted(false).success(false)).run(); callback.result(new PumpEnactResult().comment(resourceHelper.gs(R.string.pumpsuspended)).enacted(false).success(false)).run();
} }
return; return;
} }
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applySMBRequest: " + request.toString());
log.debug("applySMBRequest: " + request.toString());
// deliver SMB // deliver SMB
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.lastKnownBolusTime = activeTreatments.getLastBolusTime(); detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.getLastBolusTime();
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
detailedBolusInfo.insulin = request.smb; detailedBolusInfo.insulin = request.smb;
detailedBolusInfo.isSMB = true; detailedBolusInfo.isSMB = true;
detailedBolusInfo.source = Source.USER; detailedBolusInfo.source = Source.USER;
detailedBolusInfo.deliverAt = request.deliverAt; detailedBolusInfo.deliverAt = request.deliverAt;
if (L.isEnabled(L.APS)) aapsLogger.debug(LTag.APS, "applyAPSRequest: bolus()");
log.debug("applyAPSRequest: bolus()"); configBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, callback);
ConfigBuilderPlugin.getPlugin().getCommandQueue().bolus(detailedBolusInfo, callback);
} }
public void disconnectPump(int durationInMinutes, Profile profile) { public void disconnectPump(int durationInMinutes, Profile profile) {
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); PumpInterface pump = configBuilderPlugin.getActivePump();
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); if (pump == null)
return;
LoopPlugin.getPlugin().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L); disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L);
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) { if (pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalAbsolute(0, durationInMinutes, true, profile, new Callback() { configBuilderPlugin.getCommandQueue().tempBasalAbsolute(0, durationInMinutes, true, profile, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); Intent i = new Intent(mainApp, ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror); i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment); i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror)); i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i); mainApp.startActivity(i);
} }
} }
}); });
} else { } else {
ConfigBuilderPlugin.getPlugin().getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() { configBuilderPlugin.getCommandQueue().tempBasalPercent(0, durationInMinutes, true, profile, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); Intent i = new Intent(mainApp, ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror); i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment); i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror)); i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i); mainApp.startActivity(i);
} }
} }
}); });
} }
if (pump.getPumpDescription().isExtendedBolusCapable && activeTreatments.isInHistoryExtendedBoluslInProgress()) { if (pump.getPumpDescription().isExtendedBolusCapable && treatmentsPlugin.isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(new Callback() { configBuilderPlugin.getCommandQueue().cancelExtended(new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); Intent i = new Intent(mainApp, ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror); i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment); i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.extendedbolusdeliveryerror)); i.putExtra("title", resourceHelper.gs(R.string.extendedbolusdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i); mainApp.startActivity(i);
} }
} }
}); });
@ -693,17 +712,17 @@ public class LoopPlugin extends PluginBase {
} }
public void suspendLoop(int durationInMinutes) { public void suspendLoop(int durationInMinutes) {
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000); suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000);
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() { configBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); Intent i = new Intent(mainApp, ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror); i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment); i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror)); i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i); mainApp.startActivity(i);
} }
} }
}); });

View file

@ -5,7 +5,7 @@ import info.nightscout.androidaps.data.ProfileStore
import info.nightscout.androidaps.db.ProfileSwitch import info.nightscout.androidaps.db.ProfileSwitch
interface ProfileFunction { interface ProfileFunction {
fun getProfileName(): String? fun getProfileName(): String
fun getProfileName(customized: Boolean): String fun getProfileName(customized: Boolean): String
fun getProfileNameWithDuration(): String fun getProfileNameWithDuration(): String
fun getProfileName(time: Long, customized: Boolean, showRemainingTime: Boolean): String fun getProfileName(time: Long, customized: Boolean, showRemainingTime: Boolean): String

View file

@ -23,6 +23,7 @@ public class Objective0 extends Objective {
@Inject ConfigBuilderPlugin configBuilderPlugin; @Inject ConfigBuilderPlugin configBuilderPlugin;
@Inject VirtualPumpPlugin virtualPumpPlugin; @Inject VirtualPumpPlugin virtualPumpPlugin;
@Inject TreatmentsPlugin treatmentsPlugin; @Inject TreatmentsPlugin treatmentsPlugin;
@Inject LoopPlugin loopPlugin;
public Objective0() { public Objective0() {
super("config", R.string.objectives_0_objective, R.string.objectives_0_gate); super("config", R.string.objectives_0_objective, R.string.objectives_0_gate);
@ -69,7 +70,7 @@ public class Objective0 extends Objective {
tasks.add(new Task(R.string.loopenabled) { tasks.add(new Task(R.string.loopenabled) {
@Override @Override
public boolean isCompleted() { public boolean isCompleted() {
return LoopPlugin.getPlugin().isEnabled(PluginType.LOOP); return loopPlugin.isEnabled(PluginType.LOOP);
} }
}); });
tasks.add(new Task(R.string.apsselected) { tasks.add(new Task(R.string.apsselected) {

View file

@ -42,7 +42,8 @@ class AutomationPlugin @Inject constructor(
private val rxBus: RxBusWrapper, private val rxBus: RxBusWrapper,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val mainApp: MainApp, private val mainApp: MainApp,
private val sp :SP private val sp :SP,
private val loopPlugin: LoopPlugin
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.fragmentClass(AutomationFragment::class.qualifiedName) .fragmentClass(AutomationFragment::class.qualifiedName)
@ -170,7 +171,7 @@ class AutomationPlugin @Inject constructor(
private fun processActions() { private fun processActions() {
if (!isEnabled(PluginType.GENERAL)) if (!isEnabled(PluginType.GENERAL))
return return
if (LoopPlugin.getPlugin().isSuspended || !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) { if (loopPlugin.isSuspended || !loopPlugin.isEnabled(PluginType.LOOP)) {
aapsLogger.debug(LTag.AUTOMATION, "Loop deactivated") aapsLogger.debug(LTag.AUTOMATION, "Loop deactivated")
return return
} }

View file

@ -28,6 +28,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
@ -40,6 +41,7 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
@ -50,12 +52,15 @@ import javax.inject.Singleton
@Singleton @Singleton
class SmsCommunicatorPlugin @Inject constructor( class SmsCommunicatorPlugin @Inject constructor(
private val configBuilderPlugin: ConfigBuilderPlugin, private val sp: SP,
private val treatmentsPlugin: TreatmentsPlugin,
private val resourceHelper: ResourceHelper, private val resourceHelper: ResourceHelper,
private val constraintChecker: ConstraintChecker, private val constraintChecker: ConstraintChecker,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val rxBus: RxBusWrapper private val rxBus: RxBusWrapper,
private val profileFunction: ProfileFunction,
private val configBuilderPlugin: ConfigBuilderPlugin,
private val treatmentsPlugin: TreatmentsPlugin,
private val loopPlugin: LoopPlugin
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.fragmentClass(SmsCommunicatorFragment::class.java.name) .fragmentClass(SmsCommunicatorFragment::class.java.name)
@ -144,7 +149,7 @@ class SmsCommunicatorPlugin @Inject constructor(
private fun processSettings(ev: EventPreferenceChange?) { private fun processSettings(ev: EventPreferenceChange?) {
if (ev == null || ev.isChanged(R.string.key_smscommunicator_allowednumbers)) { if (ev == null || ev.isChanged(R.string.key_smscommunicator_allowednumbers)) {
val settings = SP.getString(R.string.key_smscommunicator_allowednumbers, "") val settings = sp.getString(R.string.key_smscommunicator_allowednumbers, "")
allowedNumbers.clear() allowedNumbers.clear()
val substrings = settings.split(";").toTypedArray() val substrings = settings.split(";").toTypedArray()
for (number in substrings) { for (number in substrings) {
@ -196,7 +201,7 @@ class SmsCommunicatorPlugin @Inject constructor(
messages.add(receivedSms) messages.add(receivedSms)
aapsLogger.debug(LTag.SMS, receivedSms.toString()) aapsLogger.debug(LTag.SMS, receivedSms.toString())
val splitted = receivedSms.text.split(Regex("\\s+")).toTypedArray() val splitted = receivedSms.text.split(Regex("\\s+")).toTypedArray()
val remoteCommandsAllowed = SP.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false) val remoteCommandsAllowed = sp.getBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)
if (splitted.isNotEmpty() && isCommand(splitted[0].toUpperCase(Locale.getDefault()), receivedSms.phoneNumber)) { if (splitted.isNotEmpty() && isCommand(splitted[0].toUpperCase(Locale.getDefault()), receivedSms.phoneNumber)) {
when (splitted[0].toUpperCase(Locale.getDefault())) { when (splitted[0].toUpperCase(Locale.getDefault())) {
"BG" -> "BG" ->
@ -292,7 +297,6 @@ class SmsCommunicatorPlugin @Inject constructor(
private fun processLOOP(splitted: Array<String>, receivedSms: Sms) { private fun processLOOP(splitted: Array<String>, receivedSms: Sms) {
when (splitted[1].toUpperCase(Locale.getDefault())) { when (splitted[1].toUpperCase(Locale.getDefault())) {
"DISABLE", "STOP" -> { "DISABLE", "STOP" -> {
val loopPlugin = LoopPlugin.getPlugin()
if (loopPlugin.isEnabled(PluginType.LOOP)) { if (loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.setPluginEnabled(PluginType.LOOP, false) loopPlugin.setPluginEnabled(PluginType.LOOP, false)
configBuilderPlugin.commandQueue.cancelTempBasal(true, object : Callback() { configBuilderPlugin.commandQueue.cancelTempBasal(true, object : Callback() {
@ -309,7 +313,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
"ENABLE", "START" -> { "ENABLE", "START" -> {
val loopPlugin = LoopPlugin.getPlugin()
if (!loopPlugin.isEnabled(PluginType.LOOP)) { if (!loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.setPluginEnabled(PluginType.LOOP, true) loopPlugin.setPluginEnabled(PluginType.LOOP, true)
sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loophasbeenenabled)) sendSMS(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loophasbeenenabled))
@ -320,7 +323,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
"STATUS" -> { "STATUS" -> {
val loopPlugin = LoopPlugin.getPlugin()
val reply = if (loopPlugin.isEnabled(PluginType.LOOP)) { val reply = if (loopPlugin.isEnabled(PluginType.LOOP)) {
if (loopPlugin.isSuspended()) String.format(resourceHelper.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend()) if (loopPlugin.isSuspended()) String.format(resourceHelper.gs(R.string.loopsuspendedfor), loopPlugin.minutesToEndOfSuspend())
else resourceHelper.gs(R.string.smscommunicator_loopisenabled) else resourceHelper.gs(R.string.smscommunicator_loopisenabled)
@ -331,7 +333,6 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
"RESUME" -> { "RESUME" -> {
LoopPlugin.getPlugin().suspendTo(0)
rxBus.send(EventRefreshOverview("SMS_LOOP_RESUME")) rxBus.send(EventRefreshOverview("SMS_LOOP_RESUME"))
NSUpload.uploadOpenAPSOffline(0.0) NSUpload.uploadOpenAPSOffline(0.0)
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed)) sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, R.string.smscommunicator_loopresumed))
@ -355,7 +356,7 @@ class SmsCommunicatorPlugin @Inject constructor(
configBuilderPlugin.commandQueue.cancelTempBasal(true, object : Callback() { configBuilderPlugin.commandQueue.cancelTempBasal(true, object : Callback() {
override fun run() { override fun run() {
if (result.success) { if (result.success) {
LoopPlugin.getPlugin().suspendTo(System.currentTimeMillis() + anInteger() * 60L * 1000) loopPlugin.suspendTo(System.currentTimeMillis() + anInteger() * 60L * 1000)
NSUpload.uploadOpenAPSOffline(anInteger() * 60.toDouble()) NSUpload.uploadOpenAPSOffline(anInteger() * 60.toDouble())
rxBus.send(EventRefreshOverview("SMS_LOOP_SUSPENDED")) rxBus.send(EventRefreshOverview("SMS_LOOP_SUSPENDED"))
val replyText = resourceHelper.gs(R.string.smscommunicator_loopsuspended) + " " + val replyText = resourceHelper.gs(R.string.smscommunicator_loopsuspended) + " " +
@ -435,7 +436,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true receivedSms.processed = true
return return
} }
val profileName = ProfileFunctions.getInstance().getProfileName() val profileName = profileFunction.getProfileName()
val list = store.getProfileList() val list = store.getProfileList()
if (splitted[1].toUpperCase(Locale.getDefault()) == "STATUS") { if (splitted[1].toUpperCase(Locale.getDefault()) == "STATUS") {
sendSMS(Sms(receivedSms.phoneNumber, profileName)) sendSMS(Sms(receivedSms.phoneNumber, profileName))
@ -503,7 +504,7 @@ class SmsCommunicatorPlugin @Inject constructor(
var tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splitted[1], "%")) var tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(splitted[1], "%"))
var duration = 30 var duration = 30
if (splitted.size > 2) duration = SafeParse.stringToInt(splitted[2]) if (splitted.size > 2) duration = SafeParse.stringToInt(splitted[2])
val profile = ProfileFunctions.getInstance().getProfile() val profile = profileFunction.getProfile()
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile)) if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile))
else if (tempBasalPct == 0 && splitted[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat)) else if (tempBasalPct == 0 && splitted[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
else if (duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat)) else if (duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
@ -535,7 +536,7 @@ class SmsCommunicatorPlugin @Inject constructor(
var tempBasal = SafeParse.stringToDouble(splitted[1]) var tempBasal = SafeParse.stringToDouble(splitted[1])
var duration = 30 var duration = 30
if (splitted.size > 2) duration = SafeParse.stringToInt(splitted[2]) if (splitted.size > 2) duration = SafeParse.stringToInt(splitted[2])
val profile = ProfileFunctions.getInstance().getProfile() val profile = profileFunction.getProfile()
if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile)) if (profile == null) sendSMS(Sms(receivedSms.phoneNumber, R.string.noprofile))
else if (tempBasal == 0.0 && splitted[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat)) else if (tempBasal == 0.0 && splitted[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
else if (duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat)) else if (duration == 0) sendSMS(Sms(receivedSms.phoneNumber, R.string.wrongformat))
@ -652,12 +653,12 @@ class SmsCommunicatorPlugin @Inject constructor(
replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true) replyText += "\n" + configBuilderPlugin.activePump?.shortStatus(true)
lastRemoteBolusTime = DateUtil.now() lastRemoteBolusTime = DateUtil.now()
if (isMeal) { if (isMeal) {
ProfileFunctions.getInstance().getProfile()?.let { currentProfile -> profileFunction.getProfile()?.let { currentProfile ->
var eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration) var eatingSoonTTDuration = sp.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration)
eatingSoonTTDuration = eatingSoonTTDuration =
if (eatingSoonTTDuration > 0) eatingSoonTTDuration if (eatingSoonTTDuration > 0) eatingSoonTTDuration
else Constants.defaultEatingSoonTTDuration else Constants.defaultEatingSoonTTDuration
var eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol else Constants.defaultEatingSoonTTmgdl) var eatingSoonTT = sp.getDouble(R.string.key_eatingsoon_target, if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol else Constants.defaultEatingSoonTTmgdl)
eatingSoonTT = eatingSoonTT =
if (eatingSoonTT > 0) eatingSoonTT if (eatingSoonTT > 0) eatingSoonTT
else if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol else if (currentProfile.units == Constants.MMOL) Constants.defaultEatingSoonTTmmol
@ -768,9 +769,9 @@ class SmsCommunicatorPlugin @Inject constructor(
defaultTargetMMOL = Constants.defaultHypoTTmmol defaultTargetMMOL = Constants.defaultHypoTTmmol
defaultTargetMGDL = Constants.defaultHypoTTmgdl defaultTargetMGDL = Constants.defaultHypoTTmgdl
} }
var ttDuration = SP.getInt(keyDuration, defaultTargetDuration) var ttDuration = sp.getInt(keyDuration, defaultTargetDuration)
ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration ttDuration = if (ttDuration > 0) ttDuration else defaultTargetDuration
var tt = SP.getDouble(keyTarget, if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL) var tt = sp.getDouble(keyTarget, if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL)
tt = Profile.toCurrentUnits(tt) tt = Profile.toCurrentUnits(tt)
tt = if (tt > 0) tt else if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL tt = if (tt > 0) tt else if (units == Constants.MMOL) defaultTargetMMOL else defaultTargetMGDL
val tempTarget = TempTarget() val tempTarget = TempTarget()
@ -816,7 +817,7 @@ class SmsCommunicatorPlugin @Inject constructor(
receivedSms.processed = true receivedSms.processed = true
messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() { messageToConfirm = AuthRequest(this, receivedSms, reply, passCode, object : SmsAction() {
override fun run() { override fun run() {
SP.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false) sp.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false)
val replyText = String.format(resourceHelper.gs(R.string.smscommunicator_stoppedsms)) val replyText = String.format(resourceHelper.gs(R.string.smscommunicator_stoppedsms))
sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText)) sendSMSToAllNumbers(Sms(receivedSms.phoneNumber, replyText))
} }

View file

@ -32,9 +32,11 @@ class StatusLinePlugin @Inject constructor(
private val rxBus: RxBusWrapper, private val rxBus: RxBusWrapper,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val resourceHelper: ResourceHelper, private val resourceHelper: ResourceHelper,
private val mainApp: MainApp,
private val configBuilderPlugin: ConfigBuilderPlugin, private val configBuilderPlugin: ConfigBuilderPlugin,
private val treatmentsPlugin: TreatmentsPlugin, private val treatmentsPlugin: TreatmentsPlugin,
private val mainApp: MainApp) : PluginBase( private val loopPlugin: LoopPlugin
) : PluginBase(
PluginDescription() PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.pluginName(R.string.xdripstatus) .pluginName(R.string.xdripstatus)
@ -60,7 +62,7 @@ class StatusLinePlugin @Inject constructor(
super.onStart() super.onStart()
disposable += rxBus.toObservable(EventRefreshOverview::class.java) disposable += rxBus.toObservable(EventRefreshOverview::class.java)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe({ if (lastLoopStatus != LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) sendStatus() }) { FabricPrivacy.logException(it) } .subscribe({ if (lastLoopStatus != loopPlugin.isEnabled(PluginType.LOOP)) sendStatus() }) { FabricPrivacy.logException(it) }
disposable += rxBus.toObservable(EventExtendedBolusChange::class.java) disposable += rxBus.toObservable(EventExtendedBolusChange::class.java)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.subscribe({ sendStatus() }) { FabricPrivacy.logException(it) } .subscribe({ sendStatus() }) { FabricPrivacy.logException(it) }
@ -108,7 +110,6 @@ class StatusLinePlugin @Inject constructor(
private fun buildStatusString(profile: Profile): String { private fun buildStatusString(profile: Profile): String {
var status = "" var status = ""
if (configBuilderPlugin.activePump == null) return "" if (configBuilderPlugin.activePump == null) return ""
val loopPlugin = LoopPlugin.getPlugin()
if (!loopPlugin.isEnabled(PluginType.LOOP)) { if (!loopPlugin.isEnabled(PluginType.LOOP)) {
status += resourceHelper.gs(R.string.disabledloop) + "\n" status += resourceHelper.gs(R.string.disabledloop) + "\n"
lastLoopStatus = false lastLoopStatus = false

View file

@ -48,7 +48,8 @@ class SWDefinition @Inject constructor(
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val localProfilePlugin: LocalProfilePlugin, private val localProfilePlugin: LocalProfilePlugin,
private val configBuilderPlugin: ConfigBuilderPlugin, private val configBuilderPlugin: ConfigBuilderPlugin,
private val objectivesPlugin: ObjectivesPlugin private val objectivesPlugin: ObjectivesPlugin,
private val loopPlugin: LoopPlugin
) { ) {
var activity: AppCompatActivity? = null var activity: AppCompatActivity? = null
@ -337,16 +338,16 @@ class SWDefinition @Inject constructor(
.add(SWButton() .add(SWButton()
.text(R.string.enableloop) .text(R.string.enableloop)
.action { .action {
LoopPlugin.getPlugin().setPluginEnabled(PluginType.LOOP, true) loopPlugin.setPluginEnabled(PluginType.LOOP, true)
LoopPlugin.getPlugin().setFragmentVisible(PluginType.LOOP, true) loopPlugin.setFragmentVisible(PluginType.LOOP, true)
configBuilderPlugin.processOnEnabledCategoryChanged(LoopPlugin.getPlugin(), PluginType.LOOP) configBuilderPlugin.processOnEnabledCategoryChanged(loopPlugin, PluginType.LOOP)
configBuilderPlugin.storeSettings("SetupWizard") configBuilderPlugin.storeSettings("SetupWizard")
rxBus.send(EventConfigBuilderChange()) rxBus.send(EventConfigBuilderChange())
rxBus.send(EventSWUpdate(true)) rxBus.send(EventSWUpdate(true))
} }
.visibility { !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) }) .visibility { !loopPlugin.isEnabled(PluginType.LOOP) })
.validator { LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) } .validator { loopPlugin.isEnabled(PluginType.LOOP) }
.visibility { !LoopPlugin.getPlugin().isEnabled(PluginType.LOOP) && Config.APS } .visibility { !loopPlugin.isEnabled(PluginType.LOOP) && Config.APS }
private val screenSensitivity = SWScreen(R.string.configbuilder_sensitivity) private val screenSensitivity = SWScreen(R.string.configbuilder_sensitivity)
.skippable(false) .skippable(false)
.add(SWInfotext() .add(SWInfotext()