Merge branch 'omnipod_eros_dev' into omnipod_eros_dev_upstream_merge

This commit is contained in:
Bart Sopers 2020-11-11 21:09:33 +01:00
commit 5e8cb2e1ed
8 changed files with 67 additions and 148 deletions

View file

@ -56,6 +56,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.source.DexcomPlugin
import info.nightscout.androidaps.plugins.source.XdripPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
@ -616,7 +617,13 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
}
pump.isSuspended -> {
overview_apsmode?.setImageResource(R.drawable.ic_loop_paused)
overview_apsmode?.setImageResource(if (pump.pumpDescription.pumpType == PumpType.Insulet_Omnipod) {
// For Omnipod, indicate the pump as disconnected when it's suspended.
// The only way to 'reconnect' it, is through the Omnipod tab
R.drawable.ic_loop_disconnected
} else {
R.drawable.ic_loop_paused
})
overview_apsmode_text?.text = ""
}

View file

@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DefaultValueHelper

View file

@ -1,16 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
public class DeliveryStatusVerificationFailedException extends OmnipodException {
private final DeliveryStatus expectedStatus;
public DeliveryStatusVerificationFailedException(DeliveryStatus expectedStatus, Throwable cause) {
super("Failed to verify delivery status (expected=" + expectedStatus + ")", cause, false);
this.expectedStatus = expectedStatus;
}
public DeliveryStatus getExpectedStatus() {
return expectedStatus;
}
}

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception;
public class PrecedingCommandFailedUncertainlyException extends OmnipodException {
public PrecedingCommandFailedUncertainlyException(Throwable cause) {
super("Preceding command failed", cause, false);
}
}

View file

@ -41,7 +41,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfo
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
@ -49,6 +48,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOut
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodProgressStatusVerificationFailedException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PrecedingCommandFailedUncertainlyException;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.Completable;
@ -175,7 +175,16 @@ public class OmnipodManager {
boolean wasSuspended = podStateManager.isSuspended();
if (!wasSuspended) {
try {
suspendDelivery(acknowledgementBeep);
} catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
throw ex;
}
// Uncertain failure
throw new PrecedingCommandFailedUncertainlyException(ex);
}
}
try {
@ -190,18 +199,10 @@ public class OmnipodManager {
throw ex;
}
// verifyDeliveryStatus will throw an exception if verification fails
if (verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) {
podStateManager.setBasalSchedule(schedule);
} else {
if (!wasSuspended) {
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex);
}
ex.setCertainFailure(true);
// Uncertain failure
throw ex;
}
}
}
// 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(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) {
@ -217,15 +218,9 @@ public class OmnipodManager {
throw ex;
}
try {
if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) {
ex.setCertainFailure(true);
throw ex;
}
} catch (DeliveryStatusVerificationFailedException ex2) {
// Uncertain failure
podStateManager.setTempBasalCertain(false);
throw ex2;
}
throw new PrecedingCommandFailedUncertainlyException(ex);
}
}
@ -241,51 +236,14 @@ public class OmnipodManager {
throw ex;
}
// verifyDeliveryStatus will throw an exception if verification fails
try {
if (verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) {
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true);
} else {
if (cancelCurrentTbr) {
throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex);
}
ex.setCertainFailure(true);
throw ex;
}
} catch (CommandFailedAfterChangingDeliveryStatusException ex2) {
// Don't set temp basal in Pod State for this Exception
throw ex2;
} catch (OmnipodException ex2) {
if (!ex2.isCertainFailure()) {
// We're not sure that setting the new TBR failed, so we assume that it succeeded
// If it didn't, PodStateManager.updateFromResponse() will fix the state
// upon receiving the next StatusResponse
// Uncertain failure
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, false);
}
throw ex2;
}
throw ex;
}
}
public synchronized void cancelTemporaryBasal(boolean acknowledgementBeep) {
try {
cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep);
} catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
throw ex;
}
try {
if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) {
ex.setCertainFailure(true);
throw ex;
}
} catch (DeliveryStatusVerificationFailedException ex2) {
podStateManager.setTempBasalCertain(false);
throw ex2;
}
}
}
private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) {
@ -423,20 +381,7 @@ public class OmnipodManager {
public synchronized void suspendDelivery(boolean acknowledgementBeep) {
assertReadyForDelivery();
try {
cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep);
} catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
throw ex;
}
// verifyDeliveryStatus will throw an exception if verification fails
if (!verifyDeliveryStatus(DeliveryStatus.SUSPENDED, ex)) {
ex.setCertainFailure(true);
throw ex;
}
}
}
// CAUTION: cancels all delivery
@ -573,28 +518,6 @@ public class OmnipodManager {
throw new PodProgressStatusVerificationFailedException(expectedPodProgressStatus, ex);
}
/**
* @param expectedStatus expected delivery status
* @param verificationCause the Exception causing us to verify the delivery status
* @return true if the Pod's status matches the expected status, otherwise false
* @throws DeliveryStatusVerificationFailedException in case reading the Pod status fails
*/
private boolean verifyDeliveryStatus(DeliveryStatus expectedStatus, Throwable verificationCause) {
aapsLogger.debug(LTag.PUMPCOMM, "Attempting to verify delivery status (expected={})", expectedStatus);
for (int i = 0; 3 > i; i++) {
try {
StatusResponse podStatus = getPodStatus();
aapsLogger.debug(LTag.PUMPCOMM, "Resolved delivery status (expected={}, actual={})", expectedStatus, podStatus.getDeliveryStatus());
return podStatus.getDeliveryStatus().equals(expectedStatus);
} catch (Exception ex) {
aapsLogger.debug(LTag.PUMPCOMM, "Ignoring exception thrown in getPodStatus() during attempt to verify delivery status: {}: {}",
ex.getClass().getSimpleName(), ex.getMessage());
}
}
aapsLogger.warn(LTag.PUMPCOMM, "Failed to verify delivery status");
throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause);
}
private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) {
if (!podStateManager.isPodActivationCompleted()) {
// No basal or temp basal is active yet

View file

@ -116,7 +116,7 @@ public abstract class PodStateManager {
}
public final void setInitializationParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone, PodProgressStatus podProgressStatus) {
if (isPodInitialized() && getPodProgressStatus().isAfter(PodProgressStatus.REMINDER_INITIALIZED)) {
if (isPodInitialized() && getActivationProgress().isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
throw new IllegalStateException("Cannot set pairing parameters: pairing parameters have already been set");
}
if (piVersion == null) {

View file

@ -46,7 +46,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
@ -55,7 +54,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedul
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException;
@ -72,6 +70,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodE
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodProgressStatusVerificationFailedException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodReturnedErrorResponseException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PrecedingCommandFailedUncertainlyException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.RileyLinkInterruptedException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.RileyLinkTimeoutException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.RileyLinkUnexpectedException;
@ -281,24 +280,22 @@ public class AapsOmnipodManager {
String errorMessage = translateException(ex.getCause());
addFailureToHistory(historyEntryType, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (DeliveryStatusVerificationFailedException ex) {
} catch (PrecedingCommandFailedUncertainlyException ex) {
if (showNotifications) {
String note;
if (ex.getExpectedStatus() == DeliveryStatus.SUSPENDED) {
// Happened when suspending delivery before setting the new profile
note = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_might_be_suspended);
} else {
// Happened when setting the new profile (after suspending delivery)
note = getStringResource(R.string.omnipod_error_set_basal_might_have_failed_delivery_might_be_suspended);
}
showNotification(Notification.FAILED_UDPATE_PROFILE, note, Notification.URGENT, R.raw.boluserror);
showNotification(Notification.FAILED_UDPATE_PROFILE, getStringResource(R.string.omnipod_error_set_basal_failed_delivery_might_be_suspended), Notification.URGENT, R.raw.boluserror);
}
String errorMessage = translateException(ex.getCause());
addFailureToHistory(historyEntryType, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (Exception ex) {
if (showNotifications) {
showNotification(Notification.FAILED_UDPATE_PROFILE, getStringResource(R.string.omnipod_error_set_basal_failed), Notification.URGENT, R.raw.boluserror);
String note;
if (OmnipodManager.isCertainFailure(ex)) {
note = getStringResource(R.string.omnipod_error_set_basal_failed);
} else {
note = getStringResource(R.string.omnipod_error_set_basal_might_have_failed_delivery_might_be_suspended);
}
showNotification(Notification.FAILED_UDPATE_PROFILE, note, Notification.URGENT, R.raw.boluserror);
}
String errorMessage = translateException(ex);
addFailureToHistory(historyEntryType, errorMessage);
@ -455,13 +452,19 @@ public class AapsOmnipodManager {
String errorMessage = translateException(ex.getCause());
addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (DeliveryStatusVerificationFailedException ex) {
} catch (PrecedingCommandFailedUncertainlyException ex) {
String errorMessage = translateException(ex.getCause());
addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage);
String note;
if (ex.getExpectedStatus() == DeliveryStatus.TEMP_BASAL_RUNNING) {
// Happened after cancelling the old TBR, when attempting to set new TBR
note = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed);
showNotification(getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled), Notification.URGENT, isNotificationUncertainTbrSoundEnabled() ? R.raw.boluserror : null);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (Exception ex) {
String errorMessage = translateException(ex);
long pumpId = addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage);
if (!OmnipodManager.isCertainFailure(ex)) {
showNotification(getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed), Notification.URGENT, isNotificationUncertainTbrSoundEnabled() ? R.raw.boluserror : null);
// Assume that setting the temp basal succeeded here, because in case it didn't succeed,
// The next StatusResponse that we receive will allow us to recover from the wrong state
@ -469,19 +472,10 @@ public class AapsOmnipodManager {
// If we would assume that the TBR didn't succeed, we couldn't properly recover upon the next StatusResponse,
// as we could only see that the Pod is running a TBR, but we don't know the rate and duration as
// the Pod doesn't provide this information
long pumpId = addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage);
addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair);
} else {
// Happened when attempting to cancel the old TBR
note = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled);
addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage);
}
showNotification(note, Notification.URGENT, isNotificationUncertainTbrSoundEnabled() ? R.raw.boluserror : null);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (Exception ex) {
String errorMessage = translateException(ex);
addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage);
addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair);
}
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
}
@ -560,7 +554,7 @@ public class AapsOmnipodManager {
String errorMessage = translateException(ex.getCause());
addFailureToHistory(PodHistoryEntryType.SET_TIME, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (DeliveryStatusVerificationFailedException ex) {
} catch (PrecedingCommandFailedUncertainlyException ex) {
if (showNotifications) {
showNotification(getStringResource(R.string.omnipod_error_set_time_failed_delivery_might_be_suspended), Notification.URGENT, R.raw.boluserror);
}
@ -568,6 +562,9 @@ public class AapsOmnipodManager {
addFailureToHistory(PodHistoryEntryType.SET_TIME, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
} catch (Exception ex) {
if (showNotifications) {
showNotification(getStringResource(R.string.omnipod_error_set_time_failed_delivery_might_be_suspended), Notification.URGENT, R.raw.boluserror);
}
String errorMessage = translateException(ex);
addFailureToHistory(PodHistoryEntryType.SET_TIME, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);

View file

@ -26,7 +26,7 @@ abstract class PodActivationActionFragmentBase : ActionFragmentBase() {
}
override fun onActionFailure() {
if (podStateManager.isPodActivationTimeExceeded && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
if ((podStateManager.isPodActivationTimeExceeded && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)) || podStateManager.isPodFaulted) {
omnipod_wizard_button_retry.visibility = View.GONE
omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE
}