Reject SMB if bolus is queued/running or outdated. Fixes 1068.
This commit is contained in:
parent
af8e1fb32f
commit
49b84fb550
4 changed files with 68 additions and 7 deletions
|
@ -10,6 +10,7 @@ import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 29.05.2017.
|
* Created by mike on 29.05.2017.
|
||||||
|
@ -17,6 +18,7 @@ import info.nightscout.androidaps.db.Source;
|
||||||
|
|
||||||
public class DetailedBolusInfo {
|
public class DetailedBolusInfo {
|
||||||
public long date = System.currentTimeMillis();
|
public long date = System.currentTimeMillis();
|
||||||
|
public long lastKnownBolusTime;
|
||||||
public String eventType = CareportalEvent.MEALBOLUS;
|
public String eventType = CareportalEvent.MEALBOLUS;
|
||||||
public double insulin = 0;
|
public double insulin = 0;
|
||||||
public double carbs = 0;
|
public double carbs = 0;
|
||||||
|
|
|
@ -520,6 +520,7 @@ public class ConfigBuilderPlugin extends PluginBase {
|
||||||
|
|
||||||
// deliver SMB
|
// deliver SMB
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
|
detailedBolusInfo.lastKnownBolusTime = activeTreatments.getLastBolusTime();
|
||||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||||
detailedBolusInfo.insulin = request.smb;
|
detailedBolusInfo.insulin = request.smb;
|
||||||
detailedBolusInfo.isSMB = true;
|
detailedBolusInfo.isSMB = true;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressHelperAc
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.commands.Command;
|
import info.nightscout.androidaps.queue.commands.Command;
|
||||||
import info.nightscout.androidaps.queue.commands.CommandBolus;
|
import info.nightscout.androidaps.queue.commands.CommandBolus;
|
||||||
import info.nightscout.androidaps.queue.commands.CommandCancelExtendedBolus;
|
import info.nightscout.androidaps.queue.commands.CommandCancelExtendedBolus;
|
||||||
|
@ -177,6 +178,18 @@ public class CommandQueue {
|
||||||
public synchronized boolean bolus(DetailedBolusInfo detailedBolusInfo, Callback callback) {
|
public synchronized boolean bolus(DetailedBolusInfo detailedBolusInfo, Callback callback) {
|
||||||
Command.CommandType type = detailedBolusInfo.isSMB ? Command.CommandType.SMB_BOLUS : Command.CommandType.BOLUS;
|
Command.CommandType type = detailedBolusInfo.isSMB ? Command.CommandType.SMB_BOLUS : Command.CommandType.BOLUS;
|
||||||
|
|
||||||
|
if (type == Command.CommandType.SMB_BOLUS) {
|
||||||
|
if (isRunning(Command.CommandType.BOLUS) || bolusInQueue()) {
|
||||||
|
log.debug("Rejecting SMB since a bolus is queue/running");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (detailedBolusInfo.lastKnownBolusTime < TreatmentsPlugin.getPlugin().getLastBolusTime()) {
|
||||||
|
log.debug("Rejecting bolus, another bolus was issued since request time");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(type.equals(Command.CommandType.BOLUS) && detailedBolusInfo.carbs > 0 && detailedBolusInfo.insulin == 0){
|
if(type.equals(Command.CommandType.BOLUS) && detailedBolusInfo.carbs > 0 && detailedBolusInfo.insulin == 0){
|
||||||
type = Command.CommandType.CARBS_ONLY_TREATMENT;
|
type = Command.CommandType.CARBS_ONLY_TREATMENT;
|
||||||
//Carbs only can be added in parallel as they can be "in the future".
|
//Carbs only can be added in parallel as they can be "in the future".
|
||||||
|
|
|
@ -15,6 +15,8 @@ import org.powermock.api.mockito.PowerMockito;
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
import org.powermock.modules.junit4.PowerMockRunner;
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.data.ConstraintChecker;
|
import info.nightscout.androidaps.data.ConstraintChecker;
|
||||||
|
@ -24,9 +26,11 @@ import info.nightscout.androidaps.interfaces.Constraint;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.commands.Command;
|
import info.nightscout.androidaps.queue.commands.Command;
|
||||||
import info.nightscout.utils.ToastUtils;
|
import info.nightscout.utils.ToastUtils;
|
||||||
|
|
||||||
|
import static info.nightscout.utils.DateUtil.now;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
@ -36,7 +40,7 @@ import static org.mockito.Mockito.when;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@RunWith(PowerMockRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, ToastUtils.class, Context.class})
|
@PrepareForTest({MainApp.class, ConfigBuilderPlugin.class, ToastUtils.class, Context.class, TreatmentsPlugin.class})
|
||||||
public class CommandQueueTest extends CommandQueue {
|
public class CommandQueueTest extends CommandQueue {
|
||||||
|
|
||||||
String validProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
|
String validProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}";
|
||||||
|
@ -142,6 +146,11 @@ public class CommandQueueTest extends CommandQueue {
|
||||||
|
|
||||||
when(MainApp.bus()).thenReturn(bus);
|
when(MainApp.bus()).thenReturn(bus);
|
||||||
when(MainApp.gs(0)).thenReturn("");
|
when(MainApp.gs(0)).thenReturn("");
|
||||||
|
|
||||||
|
PowerMockito.mockStatic(TreatmentsPlugin.class);
|
||||||
|
TreatmentsPlugin treatmentsPlugin = mock(TreatmentsPlugin.class);
|
||||||
|
when(TreatmentsPlugin.getPlugin()).thenReturn(treatmentsPlugin);
|
||||||
|
when(treatmentsPlugin.getLastBolusTime()).thenReturn(new Date(100, 0,1 ).getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,21 +168,57 @@ public class CommandQueueTest extends CommandQueue {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void callingCancelAllBolusesClearsQueue() throws Exception {
|
public void callingCancelAllBolusesClearsQueue() throws Exception {
|
||||||
|
// given
|
||||||
prepareMock(0d, 0);
|
prepareMock(0d, 0);
|
||||||
|
|
||||||
// add normal and SMB-bolus to queue
|
|
||||||
Assert.assertEquals(0, size());
|
Assert.assertEquals(0, size());
|
||||||
|
|
||||||
|
DetailedBolusInfo smb = new DetailedBolusInfo();
|
||||||
|
smb.lastKnownBolusTime = now();
|
||||||
|
smb.isSMB = true;
|
||||||
|
bolus(smb, null);
|
||||||
|
|
||||||
|
bolus(new DetailedBolusInfo(), null);
|
||||||
|
Assert.assertEquals(2, size());
|
||||||
|
|
||||||
|
// when
|
||||||
|
cancelAllBoluses();
|
||||||
|
|
||||||
|
// then
|
||||||
|
Assert.assertEquals(0, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void smbIsRejectedIfABolusIsQueued() throws Exception {
|
||||||
|
// given
|
||||||
|
prepareMock(0d, 0);
|
||||||
|
Assert.assertEquals(0, size());
|
||||||
|
|
||||||
|
// when
|
||||||
bolus(new DetailedBolusInfo(), null);
|
bolus(new DetailedBolusInfo(), null);
|
||||||
|
|
||||||
DetailedBolusInfo smb = new DetailedBolusInfo();
|
DetailedBolusInfo smb = new DetailedBolusInfo();
|
||||||
smb.isSMB = true;
|
smb.isSMB = true;
|
||||||
bolus(smb, null);
|
boolean queued = bolus(smb, null);
|
||||||
|
|
||||||
Assert.assertEquals(2, size());
|
// then
|
||||||
|
Assert.assertFalse(queued);
|
||||||
|
Assert.assertEquals(size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
// cancelling all boluses clear all boluses from the queue
|
@Test
|
||||||
cancelAllBoluses();
|
public void smbIsRejectedIfLastKnownBolusIsOutdated() throws Exception {
|
||||||
|
// given
|
||||||
|
prepareMock(0d, 0);
|
||||||
Assert.assertEquals(0, size());
|
Assert.assertEquals(0, size());
|
||||||
|
|
||||||
|
// when
|
||||||
|
DetailedBolusInfo bolus = new DetailedBolusInfo();
|
||||||
|
bolus.isSMB = true;
|
||||||
|
bolus.lastKnownBolusTime = 0;
|
||||||
|
boolean queued = bolus(bolus, null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Assert.assertFalse(queued);
|
||||||
|
Assert.assertEquals(size(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue