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 6ba8d2122c..3262014a58 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 @@ -26,7 +26,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetBasalSched import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetTempBasalAction; import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.InsertCannulaService; import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.PrimeService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.SetTempBasalService; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.CancelDeliveryCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentHighFlashLogDump; @@ -203,15 +202,30 @@ public class OmnipodManager { } } + // CAUTION: cancels temp basal and then sets new temp basal. An OmnipodException[certainFailure=false] indicates that the pod might have cancelled the previous temp basal, but did not set a new temp basal public synchronized void setTemporaryBasal(TempBasalPair tempBasalPair, boolean acknowledgementBeep, boolean completionBeep) { assertReadyForDelivery(); logStartingCommandExecution("setTemporaryBasal [tempBasalPair=" + tempBasalPair + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]"); try { - executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction(new SetTempBasalService(), + // Never emit a beep for cancelling temp basal, so if the user has beeps enabled, + // they can verify that setting the temp basal succeeded (and not cancelling it) + cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), false); + } catch (Exception ex) { + logCommandExecutionFinished("setTemporaryBasal"); + throw ex; + } + + try { + executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( podState, tempBasalPair.getInsulinRate(), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), acknowledgementBeep, completionBeep))); + } catch (OmnipodException ex) { + // Treat all exceptions as uncertain failures, because all delivery has been suspended here. + // Setting this to an uncertain failure will enable for the user to get an appropriate warning + ex.setCertainFailure(false); + throw ex; } finally { logCommandExecutionFinished("setTemporaryBasal"); } @@ -404,12 +418,12 @@ public class OmnipodManager { // Try to get pulse log for diagnostics // FIXME replace by storing to file - if(isLoggingEnabled()) { + if (isLoggingEnabled()) { try { PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podState, PodInfoType.RECENT_HIGH_FLASH_LOG_DUMP)); PodInfoRecentHighFlashLogDump pulseLogInfo = podInfoResponse.getPodInfo(); LOG.info("Retrieved pulse log from the pod: {}", pulseLogInfo.toString()); - } catch(Exception ex) { + } catch (Exception ex) { LOG.warn("Failed to retrieve pulse log from the pod", ex); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java index edff5b48dd..686fc0036b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java @@ -34,11 +34,6 @@ public class CancelDeliveryAction implements OmnipodAction { this.acknowledgementBeep = acknowledgementBeep; } - public CancelDeliveryAction(PodSessionState podState, DeliveryType deliveryType, - boolean acknowledgementBeep) { - this(podState, EnumSet.of(deliveryType), acknowledgementBeep); - } - @Override public StatusResponse execute(OmnipodCommunicationService communicationService) { List messageBlocks = new ArrayList<>(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java index 059ed0645d..24dc6cbcb0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java @@ -28,7 +28,6 @@ public class DeactivatePodAction implements OmnipodAction { EnumSet.allOf(DeliveryType.class), acknowledgementBeep)); } - DeactivatePodCommand deactivatePodCommand = new DeactivatePodCommand(podState.getCurrentNonce()); - return communicationService.sendCommand(StatusResponse.class, podState, deactivatePodCommand); + return communicationService.sendCommand(StatusResponse.class, podState, new DeactivatePodCommand(podState.getCurrentNonce())); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java index 2f36a93c27..f954a2c466 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java @@ -9,9 +9,12 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessa import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BasalScheduleExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; 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.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.exception.IllegalDeliveryStatusException; public class SetBasalScheduleAction implements OmnipodAction { private final PodSessionState podState; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java index 7007fdb741..52c37d329c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java @@ -2,34 +2,33 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; import org.joda.time.Duration; +import java.util.Arrays; +import java.util.List; + import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.SetTempBasalService; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.TempBasalExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; import info.nightscout.androidaps.plugins.pump.omnipod.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.IllegalDeliveryStatusException; public class SetTempBasalAction implements OmnipodAction { - private final SetTempBasalService service; private final PodSessionState podState; private final double rate; private final Duration duration; private final boolean acknowledgementBeep; private final boolean completionBeep; - public SetTempBasalAction(SetTempBasalService setTempBasalService, PodSessionState podState, - double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) { - if (setTempBasalService == null) { - throw new ActionInitializationException("Set temp basal service cannot be null"); - } + public SetTempBasalAction(PodSessionState podState, double rate, Duration duration, + boolean acknowledgementBeep, boolean completionBeep) { if (podState == null) { throw new ActionInitializationException("Pod state cannot be null"); } if (duration == null) { throw new ActionInitializationException("Duration cannot be null"); } - this.service = setTempBasalService; this.podState = podState; this.rate = rate; this.duration = duration; @@ -39,13 +38,11 @@ public class SetTempBasalAction implements OmnipodAction { @Override public StatusResponse execute(OmnipodCommunicationService communicationService) { - StatusResponse statusResponse = service.cancelTempBasal(communicationService, podState); + List messageBlocks = Arrays.asList( // + new SetInsulinScheduleCommand(podState.getCurrentNonce(), rate, duration), + new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); - if (statusResponse.getDeliveryStatus() != DeliveryStatus.NORMAL) { - throw new IllegalDeliveryStatusException(DeliveryStatus.NORMAL, statusResponse.getDeliveryStatus()); - } - - return service.executeTempBasalCommand(communicationService, podState, rate, duration, - acknowledgementBeep, completionBeep); + OmnipodMessage message = new OmnipodMessage(podState.getAddress(), messageBlocks, podState.getMessageNumber()); + return communicationService.exchangeMessages(StatusResponse.class, podState, message); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/SetTempBasalService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/SetTempBasalService.java deleted file mode 100644 index 540217f4c6..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/SetTempBasalService.java +++ /dev/null @@ -1,33 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service; - -import org.joda.time.Duration; - -import java.util.Arrays; -import java.util.List; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.CancelDeliveryAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.TempBasalExtraCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; - -public class SetTempBasalService { - public StatusResponse cancelTempBasal(OmnipodCommunicationService communicationService, PodSessionState podState) { - return communicationService.executeAction(new CancelDeliveryAction(podState, DeliveryType.TEMP_BASAL, false)); - } - - public StatusResponse executeTempBasalCommand(OmnipodCommunicationService communicationService, - PodSessionState podState, double rate, Duration duration, - boolean acknowledgementBeep, boolean completionBeep) { - List messageBlocks = Arrays.asList( // - new SetInsulinScheduleCommand(podState.getCurrentNonce(), rate, duration), - new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); - - OmnipodMessage message = new OmnipodMessage(podState.getAddress(), messageBlocks, podState.getMessageNumber()); - return communicationService.exchangeMessages(StatusResponse.class, podState, message); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java index 081281b570..05501acaa3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java @@ -5,10 +5,13 @@ import com.google.gson.Gson; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Duration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; +import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; @@ -26,6 +29,8 @@ import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.SP; public class PodSessionState extends PodState { + private static final Logger LOG = LoggerFactory.getLogger(L.PUMPCOMM); + private final Map configuredAlerts; private transient PodStateChangedHandler stateChangedHandler; private DateTime activatedAt; @@ -234,7 +239,11 @@ public class PodSessionState extends PodState { expiresAt = expiresAtCalculated; } - suspended = (statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED); + boolean newSuspendedState = statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED; + if (suspended != newSuspendedState) { + LOG.info("Updating pod suspended state in updateFromStatusResponse. newSuspendedState={}, statusResponse={}", newSuspendedState, statusResponse.toString()); + suspended = newSuspendedState; + } activeAlerts = statusResponse.getAlerts(); lastDeliveryStatus = statusResponse.getDeliveryStatus(); reservoirLevel = statusResponse.getReservoirLevel(); 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 ba5b2bd842..dc9d16cf6c 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 @@ -335,6 +335,10 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface delegate.setTemporaryBasal(tempBasalPair, beepsEnabled, beepsEnabled); addSuccessToHistory(time, PodHistoryEntryType.SetTemporaryBasal, tempBasalPair); } catch (Exception ex) { + if ((ex instanceof OmnipodException) && !((OmnipodException) ex).isCertainFailure()) { + addToHistory(time, PodHistoryEntryType.SetTemporaryBasal, "Uncertain failure", false); + return new PumpEnactResult().success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_set_temp_basal_failed_uncertain)); + } String comment = handleAndTranslateException(ex); addFailureToHistory(time, PodHistoryEntryType.SetTemporaryBasal, comment); return new PumpEnactResult().success(false).enacted(false).comment(comment); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78b7161bf9..d903acd011 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1744,8 +1744,9 @@ Shutdown is imminent Low reservoir Unknown alert - Setting basal profile failed. Delivery might be suspended! Please refresh pod status. - Setting time failed. Delivery might be suspended! Please refresh pod status. + Setting basal profile might have failed. Delivery might be suspended! Please refresh pod status. + Setting temp basal might have failed. If there was a temp basal already running, that may have been cancelled! Please refresh pod status. + Setting time might have failed. Delivery might be suspended! Please refresh pod status. Unable to verify whether the bolus succeeded. Please verify that your pod is bolusing or cancel the bolus.