From f2e439a48561c7b8a271b4906465148871f51a8e Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 30 Nov 2019 15:16:53 +0100 Subject: [PATCH] Calculate bolus durations and add bolus completion handler in OmnipodManager --- .../pump/omnipod/comm/OmnipodManager.java | 57 ++++++++++--------- .../omnipod/comm/StatusResponseHandler.java | 8 +++ .../pump/omnipod/defs/DeliveryStatus.java | 4 ++ .../driver/comm/AapsOmnipodManager.java | 20 ++++++- .../pump/omnipod/util/OmnipodConst.java | 5 +- 5 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/StatusResponseHandler.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java index 04d0fb6b49..0570d2ce3f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java @@ -34,11 +34,12 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.exception.IllegalSetupProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.utils.SP; public class OmnipodManager { - private static final int SETUP_ACTION_VERIFICATION_TRIES = 3; + private static final int ACTION_VERIFICATION_TRIES = 3; protected final OmnipodCommunicationService communicationService; protected PodSessionState podState; @@ -64,7 +65,7 @@ public class OmnipodManager { executeDelayed(() -> verifySetupAction(statusResponse -> PrimeAction.updatePrimingStatus(podState, statusResponse), // SetupProgress.PRIMING_FINISHED, resultHandler), // - OmnipodConst.POD_PRIME_DURATION); + calculateBolusDuration(OmnipodConst.POD_PRIME_BOLUS_UNITS, OmnipodConst.POD_PRIMING_DELIVERY_RATE)); } else { // TODO use string resource return new PumpEnactResult().success(false).enacted(false).comment("Illegal setup state: " + podState.getSetupProgress().name()); @@ -95,7 +96,7 @@ public class OmnipodManager { executeDelayed(() -> verifySetupAction(statusResponse -> InsertCannulaAction.updateCannulaInsertionStatus(podState, statusResponse), // SetupProgress.COMPLETED, resultHandler), - OmnipodConst.POD_CANNULA_INSERTION_DURATION); + calculateBolusDuration(OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConst.POD_CANNULA_INSERTION_DELIVERY_RATE)); } catch (Exception ex) { // TODO distinguish between certain and uncertain failures // TODO user friendly error messages (string resources) @@ -121,22 +122,12 @@ public class OmnipodManager { return new PumpEnactResult().success(true).enacted(true); } - public PumpEnactResult getPodStatus() { + public StatusResponse getPodStatus() { if (podState == null) { - // TODO use string resource - return new PumpEnactResult().success(false).enacted(false).comment("Pod should be paired and primed first"); + throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, null); } - try { - // TODO how can we return the status response? Also refer to TODO in interface - StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podState)); - } catch (Exception ex) { - // TODO distinguish between certain and uncertain failures - // TODO user friendly error messages (string resources) - return new PumpEnactResult().success(false).enacted(false).comment(ex.getMessage()); - } - - return new PumpEnactResult().success(true).enacted(true); + return communicationService.executeAction(new GetStatusAction(podState)); } public PumpEnactResult deactivatePod() { @@ -181,20 +172,36 @@ public class OmnipodManager { return new PumpEnactResult().success(true).enacted(true); } - public PumpEnactResult bolus(Double units) { + public PumpEnactResult bolus(Double units, StatusResponseHandler bolusCompletionHandler) { if (!isInitialized()) { return createNotInitializedResult(); } try { communicationService.executeAction(new BolusAction(podState, units, true, true)); + + if(bolusCompletionHandler != null) { + executeDelayed(() -> { + for (int i = 0; ACTION_VERIFICATION_TRIES > i; i++) { + StatusResponse statusResponse = null; + try { + statusResponse = getPodStatus(); + if (statusResponse.getDeliveryStatus().isBolusing()) { + break; + } + } catch (Exception ex) { + // Ignore + } + bolusCompletionHandler.handle(statusResponse); + } + }, calculateBolusDuration(units, OmnipodConst.POD_BOLUS_DELIVERY_RATE)); + } } catch (Exception ex) { // TODO distinguish between certain and uncertain failures // TODO user friendly error messages (string resources) return new PumpEnactResult().success(false).enacted(false).comment(ex.getMessage()); } - // TODO calculate bolus duration return new PumpEnactResult().success(true).enacted(true); } @@ -339,6 +346,10 @@ public class OmnipodManager { return podState == null ? "null" : podState.toString(); } + private Duration calculateBolusDuration(double units, double deliveryRate) { + return Duration.standardSeconds((long)Math.ceil(units / deliveryRate)); + } + private void executeDelayed(Runnable r, Duration timeout) { ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); scheduledExecutorService.schedule(r, timeout.getMillis(), TimeUnit.MILLISECONDS); @@ -355,7 +366,7 @@ public class OmnipodManager { private void verifySetupAction(StatusResponseHandler statusResponseHandler, SetupProgress expectedSetupProgress, SetupActionResultHandler resultHandler) { SetupActionResult result = null; - for (int i = 0; SETUP_ACTION_VERIFICATION_TRIES > i; i++) { + for (int i = 0; ACTION_VERIFICATION_TRIES > i; i++) { try { StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podState)); statusResponseHandler.handle(delayedStatusResponse); @@ -376,11 +387,5 @@ public class OmnipodManager { if (resultHandler != null) { resultHandler.handle(result); } - } - - @FunctionalInterface - private interface StatusResponseHandler { - void handle(StatusResponse podState); - } -} \ No newline at end of file +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/StatusResponseHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/StatusResponseHandler.java new file mode 100644 index 0000000000..d29fb48a69 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/StatusResponseHandler.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.comm; + +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; + +@FunctionalInterface +public interface StatusResponseHandler { + void handle(StatusResponse statusResponse); +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java index a85095fddd..9df1d480a5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java @@ -26,4 +26,8 @@ public enum DeliveryStatus { public byte getValue() { return value; } + + public boolean isBolusing() { + return this.equals(BOLUS_IN_PROGRESS) || this.equals(BOLUS_AND_TEMP_BASAL); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java index 41e595f6e0..5bd181c50e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java @@ -13,6 +13,7 @@ import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationService; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodManager; import info.nightscout.androidaps.plugins.pump.omnipod.comm.SetupActionResult; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; @@ -66,7 +67,13 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface @Override public PumpEnactResult getPodStatus() { - return delegate.getPodStatus(); + try { + StatusResponse statusResponse = delegate.getPodStatus(); + return new PumpEnactResult().success(true).enacted(false); + } catch(Exception ex) { + // TODO return string resource + return new PumpEnactResult().success(false).enacted(false).comment(ex.getMessage()); + } } @Override @@ -104,7 +111,16 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface @Override public PumpEnactResult setBolus(Double amount) { - return delegate.bolus(amount); + return delegate.bolus(amount, statusResponse -> { + if(statusResponse == null) { + // Failed to retrieve status response after bolus + // Bolus probably finished anyway + } else if(statusResponse.getDeliveryStatus().isBolusing()) { + // This shouldn't happen + } else { + // Bolus successfully completed + } + }); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java index 3436836795..e284093b28 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java @@ -26,6 +26,9 @@ public class OmnipodConst { } public static final double POD_PULSE_SIZE = 0.05; + public static final double POD_BOLUS_DELIVERY_RATE = 0.025; // units per second + public static final double POD_PRIMING_DELIVERY_RATE = 0.05; // units per second + public static final double POD_CANNULA_INSERTION_DELIVERY_RATE = 0.05; // units per second public static final double MAX_RESERVOIR_READING = 50.0; public static final double MAX_BOLUS = 30.0; public static final double MAX_BASAL_RATE = 30.0; @@ -39,6 +42,4 @@ public class OmnipodConst { public static final double POD_PRIME_BOLUS_UNITS = 2.6; public static final double POD_CANNULA_INSERTION_BOLUS_UNITS = 0.5; - public static final Duration POD_PRIME_DURATION = Duration.standardSeconds(55); - public static final Duration POD_CANNULA_INSERTION_DURATION = Duration.standardSeconds(10); }