Merge remote-tracking branch 'origin/dev' into combo-scripter-v2

* origin/dev:
  fix canceling temp in open loop mode. credits to @warstar2187
  prevent basal updated messages on virtual pump
  added BolusWizardTest
  prefill profile switch JSON from local store if not exists
  PARTIAL_WAKE_LOCK for NSClientService
This commit is contained in:
Johannes Mockenhaupt 2018-01-09 20:59:37 +01:00
commit 9a74b0fb95
No known key found for this signature in database
GPG key ID: 9E1EA6AF7BBBB0D1
9 changed files with 139 additions and 8 deletions

View file

@ -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'

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -227,7 +227,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
@Override
public boolean isThisProfileSet(Profile profile) {
return false;
return true;
}
@Override

View file

@ -811,6 +811,7 @@
<string name="hasbgdata">BG available from selected source</string>
<string name="basalprofilenotaligned">Basal values not aligned to hours</string>
<string name="zerovalueinprofile">Zero value in profile</string>
<string name="nolocaleprofilefound">Received profile switch from NS but profile doesn\'t exist localy</string>
<string name="bolusstopping">Stopping bolus delivery</string>
<string name="bolusstopped">Bolus delivery stopped</string>
<string name="combo_programming_bolus">Programming pump for bolusing</string>

View file

@ -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;
}
}