diff --git a/app/build.gradle b/app/build.gradle index e5e9edaf9c..d6b4f914f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -178,6 +178,10 @@ dependencies { compile 'junit:junit:4.12' testCompile 'org.json:json:20140107' testCompile 'org.mockito:mockito-core:2.7.22' + testCompile 'org.powermock:powermock-api-mockito2:1.7.3' + testCompile 'org.powermock:powermock-module-junit4-rule-agent:1.7.3' + testCompile 'org.powermock:powermock-module-junit4-rule:1.7.3' + testCompile 'org.powermock:powermock-module-junit4:1.7.3' androidTestCompile 'org.mockito:mockito-core:2.7.22' androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index b89da43de4..e4e627d711 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -30,7 +30,9 @@ import java.util.concurrent.TimeUnit; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.events.EventCareportalEventChange; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventFoodDatabaseChanged; @@ -43,7 +45,10 @@ import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTempTargetChange; import info.nightscout.androidaps.events.EventTreatmentChange; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpDanaR.activities.DanaRNSHistorySync; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.utils.PercentageSplitter; @@ -1709,6 +1714,19 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { profileSwitch.percentage = trJson.getInt("percentage"); if (trJson.has("profileJson")) profileSwitch.profileJson = trJson.getString("profileJson"); + else { + ProfileStore store = ConfigBuilderPlugin.getActiveProfileInterface().getProfile(); + Profile profile = store.getSpecificProfile(profileSwitch.profileName); + if (profile != null) { + profileSwitch.profileJson = profile.getData().toString(); + log.debug("Profile switch prefilled with JSON from local store"); + } else { + Notification notification = new Notification(Notification.NO_LOCALE_PROFILE_FOUND, MainApp.sResources.getString(R.string.nolocaleprofilefound), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(notification)); + log.debug("JSON for profile switch doesn't exist. Ignoring ..."); + return; + } + } if (trJson.has("profilePlugin")) profileSwitch.profilePlugin = trJson.getString("profilePlugin"); createOrUpdate(profileSwitch); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java index abd0f2b26b..1ef71c2f75 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java @@ -114,6 +114,18 @@ public class NSClientService extends Service { initialize(); } + @Override + public void onCreate() { + super.onCreate(); + mWakeLock.acquire(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mWakeLock.release(); + } + public class LocalBinder extends Binder { public NSClientService getServiceInstance() { return NSClientService.this; @@ -182,8 +194,6 @@ public class NSClientService extends Service { public void initialize() { dataCounter = 0; - NSClientService.mWakeLock.acquire(); - readPreferences(); if (!nsAPISecret.equals("")) @@ -221,7 +231,6 @@ public class NSClientService extends Service { MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "No NS URL specified")); MainApp.bus().post(new EventNSClientStatus("Not configured")); } - NSClientService.mWakeLock.release(); } private Emitter.Listener onConnect = new Emitter.Listener() { @@ -242,6 +251,15 @@ public class NSClientService extends Service { public void destroy() { if (mSocket != null) { + mSocket.off(Socket.EVENT_CONNECT); + mSocket.off(Socket.EVENT_DISCONNECT); + mSocket.off(Socket.EVENT_PING); + mSocket.off("dataUpdate"); + mSocket.off("announcement"); + mSocket.off("alarm"); + mSocket.off("urgent_alarm"); + mSocket.off("clear_alarm"); + MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "destroy")); isConnected = false; hasWriteAuth = false; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java index 4dcb174209..4c14f33533 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java @@ -248,9 +248,11 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { determineBasalResultAMA.changeRequested = false; // limit requests on openloop mode if (!MainApp.getConfigBuilder().isClosedModeEnabled()) { - if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) + if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultAMA.rate == 0 && determineBasalResultAMA.duration == 0) { + // going to cancel + } else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) { determineBasalResultAMA.changeRequested = false; - if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) + } else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultAMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) determineBasalResultAMA.changeRequested = false; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java index ac360d4ec8..d56dc44b89 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java @@ -232,9 +232,11 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { determineBasalResultMA.changeRequested = false; // limit requests on openloop mode if (!MainApp.getConfigBuilder().isClosedModeEnabled()) { - if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) + if (MainApp.getConfigBuilder().isTempBasalInProgress() && determineBasalResultMA.rate == 0 && determineBasalResultMA.duration == 0) { + // going to cancel + } else if (MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory()) < 0.1) { determineBasalResultMA.changeRequested = false; - if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) + } else if (!MainApp.getConfigBuilder().isTempBasalInProgress() && Math.abs(determineBasalResultMA.rate - ConfigBuilderPlugin.getActivePump().getBaseBasalRate()) < 0.1) determineBasalResultMA.changeRequested = false; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java index 34ad8ff7ba..da2a6b04aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java @@ -60,6 +60,7 @@ public class Notification { public static final int MINIMAL_BASAL_VALUE_REPLACED = 29; public static final int BASAL_PROFILE_NOT_ALIGNED_TO_HOURS = 30; public static final int ZERO_VALUE_IN_PROFILE = 31; + public static final int NO_LOCALE_PROFILE_FOUND = 32; public int id; public Date date; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index 7c777a5652..cb05517cfc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -227,7 +227,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { @Override public boolean isThisProfileSet(Profile profile) { - return false; + return true; } @Override diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 03e37403f3..5cfb588165 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -811,6 +811,7 @@ BG available from selected source Basal values not aligned to hours Zero value in profile + Received profile switch from NS but profile doesn\'t exist localy Stopping bolus delivery Bolus delivery stopped Programming pump for bolusing diff --git a/app/src/test/java/info/nightscout/utils/BolusWizardTest.java b/app/src/test/java/info/nightscout/utils/BolusWizardTest.java new file mode 100644 index 0000000000..21872f47bc --- /dev/null +++ b/app/src/test/java/info/nightscout/utils/BolusWizardTest.java @@ -0,0 +1,85 @@ +package info.nightscout.utils; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.data.IobTotal; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.db.Treatment; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Created by kuchjir on 12/12/2017. + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest( { MainApp.class, GlucoseStatus.class, ConfigBuilderPlugin.class }) +public class BolusWizardTest { + private static final double PUMP_BOLUS_STEP = 0.1; + + @Test + /** Should calculate the same bolus when different blood glucose but both in target range */ + public void shuldCalculateTheSameBolusWhenBGsInRange() throws Exception { + BolusWizard bw = new BolusWizard(); + Profile profile = setupProfile(4d, 8d, 20d, 12d); + + Double bolusForBg42 = bw.doCalc(profile, null, 20, 0.0,4.2, 0d, 100d, true, true, false, false); + Double bolusForBg54 = bw.doCalc(profile, null, 20, 0.0,5.4, 0d, 100d, true, true, false, false); + Assert.assertEquals(bolusForBg42, bolusForBg54); + } + + @Test + public void shuldCalculateHigherBolusWhenHighBG() throws Exception { + BolusWizard bw = new BolusWizard(); + Profile profile = setupProfile(4d, 8d, 20d, 12d); + + Double bolusForHighBg = bw.doCalc(profile, null, 20, 0d,9.8, 0d, 100d, true, true, false, false); + Double bolusForBgInRange = bw.doCalc(profile, null, 20, 0.0,5.4, 0d, 100d, true, true, false, false); + Assert.assertTrue(bolusForHighBg > bolusForBgInRange); + } + + @Test + public void shuldCalculateLowerBolusWhenLowBG() throws Exception { + BolusWizard bw = new BolusWizard(); + Profile profile = setupProfile(4d, 8d, 20d, 12d); + + Double bolusForLowBg = bw.doCalc(profile, null, 20, 0d,3.6, 0d, 100d, true, true, false, false); + Double bolusForBgInRange = bw.doCalc(profile, null, 20, 0.0,5.4, 0d, 100d, true, true, false, false); + Assert.assertTrue(bolusForLowBg < bolusForBgInRange); + } + + private Profile setupProfile(Double targetLow, Double targetHigh, Double insulinSensitivityFactor, Double insulinToCarbRatio) { + Profile profile = mock(Profile.class); + when(profile.getTargetLow()).thenReturn(targetLow); + when(profile.getTargetHigh()).thenReturn(targetHigh); + when(profile.getIsf()).thenReturn(insulinSensitivityFactor); + when(profile.getIc()).thenReturn(insulinToCarbRatio); + + PowerMockito.mockStatic(GlucoseStatus.class); + when(GlucoseStatus.getGlucoseStatusData()).thenReturn(null); + + ConfigBuilderPlugin treatment = mock(ConfigBuilderPlugin.class); + IobTotal iobTotalZero = new IobTotal(System.currentTimeMillis()); + when(treatment.getLastCalculationTreatments()).thenReturn(iobTotalZero); + when(treatment.getLastCalculationTempBasals()).thenReturn(iobTotalZero); + PowerMockito.mockStatic(MainApp.class); + when(MainApp.getConfigBuilder()).thenReturn(treatment); + + PowerMockito.mockStatic(ConfigBuilderPlugin.class); + PumpInterface pump = MDIPlugin.getPlugin(); + pump.getPumpDescription().bolusStep = PUMP_BOLUS_STEP; + when(ConfigBuilderPlugin.getActivePump()).thenReturn(pump); + + return profile; + } +} \ No newline at end of file