Add async feedback to pod init steps
This commit is contained in:
parent
5b3ca232e9
commit
f2615d977b
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.Duration;
|
||||
|
@ -15,7 +13,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
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.action.AcknowledgeAlertsAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.BolusAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.CancelDeliveryAction;
|
||||
|
@ -23,7 +20,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.DeactivatePod
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.GetPodInfoAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.GetStatusAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.InsertCannulaAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.OmnipodAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.PairAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.PrimeAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetBasalScheduleAction;
|
||||
|
@ -43,6 +39,8 @@ 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;
|
||||
|
||||
protected final OmnipodCommunicationService communicationService;
|
||||
protected PodSessionState podState;
|
||||
|
||||
|
@ -54,7 +52,37 @@ public class OmnipodManager {
|
|||
this.podState = podState;
|
||||
}
|
||||
|
||||
public PumpEnactResult insertCannula(Profile profile) {
|
||||
// Returns a PumpEnactResult which describes whether or not all commands have been sent successfully
|
||||
// After priming should have finished (55 seconds), the pod state is verified.
|
||||
// The result of that verification is passed to the SetupActionResultHandler
|
||||
public PumpEnactResult pairAndPrime(SetupActionResultHandler resultHandler) {
|
||||
try {
|
||||
if (podState == null) {
|
||||
podState = communicationService.executeAction(new PairAction(new PairService()));
|
||||
}
|
||||
if (podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) {
|
||||
communicationService.executeAction(new PrimeAction(new PrimeService(), podState));
|
||||
|
||||
executeDelayed(() -> verifySetupAction(statusResponse -> PrimeAction.updatePrimingStatus(podState, statusResponse), //
|
||||
SetupProgress.PRIMING_FINISHED, resultHandler), //
|
||||
OmnipodConst.POD_PRIME_DURATION);
|
||||
} else {
|
||||
// TODO use string resource
|
||||
return new PumpEnactResult().success(false).enacted(false).comment("Illegal setup state: " + podState.getSetupProgress().name());
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
// Returns a PumpEnactResult which describes whether or not all commands have been sent successfully
|
||||
// After inserting the cannula should have finished (10 seconds), the pod state is verified.
|
||||
// The result of that verification is passed to the SetupActionResultHandler
|
||||
public PumpEnactResult insertCannula(Profile profile, SetupActionResultHandler resultHandler) {
|
||||
if (podState == null || podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) {
|
||||
// TODO use string resource
|
||||
return new PumpEnactResult().success(false).enacted(false).comment("Pod should be paired and primed first");
|
||||
|
@ -67,39 +95,9 @@ public class OmnipodManager {
|
|||
communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podState,
|
||||
BasalScheduleMapper.mapProfileToBasalSchedule(profile)));
|
||||
|
||||
executeDelayed(() -> {
|
||||
// TODO improve: repeat get status when it fails and handle unexpected statuses
|
||||
// TODO give user feedback when priming finished (or somehow failed)
|
||||
StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podState));
|
||||
InsertCannulaAction.updateCannulaInsertionStatus(podState, delayedStatusResponse);
|
||||
}, OmnipodConst.POD_CANNULA_INSERTION_DURATION);
|
||||
} 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);
|
||||
}
|
||||
|
||||
public PumpEnactResult pairAndPrime() {
|
||||
try {
|
||||
if (podState == null) {
|
||||
podState = communicationService.executeAction(new PairAction(new PairService()));
|
||||
}
|
||||
if (podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) {
|
||||
communicationService.executeAction(new PrimeAction(new PrimeService(), podState));
|
||||
|
||||
executeDelayed(() -> {
|
||||
// TODO improve: repeat get status when it fails and handle unexpected statuses
|
||||
// TODO give user feedback when priming finished (or somehow failed)
|
||||
StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podState));
|
||||
PrimeAction.updatePrimingStatus(podState, delayedStatusResponse);
|
||||
}, OmnipodConst.POD_PRIME_DURATION);
|
||||
} else {
|
||||
// TODO use string resource
|
||||
return new PumpEnactResult().success(false).enacted(false).comment("Illegal setup state: " + podState.getSetupProgress().name());
|
||||
}
|
||||
executeDelayed(() -> verifySetupAction(statusResponse -> InsertCannulaAction.updateCannulaInsertionStatus(podState, statusResponse), //
|
||||
SetupProgress.COMPLETED, resultHandler),
|
||||
OmnipodConst.POD_CANNULA_INSERTION_DURATION);
|
||||
} catch (Exception ex) {
|
||||
// TODO distinguish between certain and uncertain failures
|
||||
// TODO user friendly error messages (string resources)
|
||||
|
@ -357,4 +355,35 @@ public class OmnipodManager {
|
|||
public PodSessionState getPodState() {
|
||||
return this.podState;
|
||||
}
|
||||
|
||||
private void verifySetupAction(StatusResponseHandler statusResponseHandler, SetupProgress expectedSetupProgress, SetupActionResultHandler resultHandler) {
|
||||
SetupActionResult result = null;
|
||||
for (int i = 0; SETUP_ACTION_VERIFICATION_TRIES > i; i++) {
|
||||
try {
|
||||
StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podState));
|
||||
statusResponseHandler.handle(delayedStatusResponse);
|
||||
|
||||
if (podState.getSetupProgress().equals(expectedSetupProgress)) {
|
||||
result = new SetupActionResult(SetupActionResult.ResultType.SUCCESS);
|
||||
break;
|
||||
} else {
|
||||
result = new SetupActionResult(SetupActionResult.ResultType.FAILURE) //
|
||||
.setupProgress(podState.getSetupProgress());
|
||||
break;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
result = new SetupActionResult(SetupActionResult.ResultType.VERIFICATION_FAILURE) //
|
||||
.exception(ex);
|
||||
}
|
||||
}
|
||||
if (resultHandler != null) {
|
||||
resultHandler.handle(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface StatusResponseHandler {
|
||||
void handle(StatusResponse podState);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress;
|
||||
|
||||
public class SetupActionResult {
|
||||
private final ResultType resultType;
|
||||
private String message;
|
||||
private Exception exception;
|
||||
private SetupProgress setupProgress;
|
||||
|
||||
public SetupActionResult(ResultType resultType) {
|
||||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
public SetupActionResult message(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetupActionResult exception(Exception ex) {
|
||||
exception = ex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SetupActionResult setupProgress(SetupProgress setupProgress) {
|
||||
this.setupProgress = setupProgress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ResultType getResultType() {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public SetupProgress getSetupProgress() {
|
||||
return setupProgress;
|
||||
}
|
||||
|
||||
public enum ResultType {
|
||||
SUCCESS(true),
|
||||
VERIFICATION_FAILURE(false),
|
||||
FAILURE(false);
|
||||
|
||||
private final boolean success;
|
||||
|
||||
ResultType(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.comm;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SetupActionResultHandler {
|
||||
void handle(SetupActionResult result);
|
||||
}
|
|
@ -15,7 +15,7 @@ public enum PodProgressStatus {
|
|||
TWO_NOT_USED_BUT_IN_33((byte) 0x0b),
|
||||
THREE_NOT_USED_BUT_IN_33((byte) 0x0c),
|
||||
ERROR_EVENT_LOGGED_SHUTTING_DOWN((byte) 0x0d),
|
||||
DELAYED_PRIME((byte) 0x0e),
|
||||
a((byte) 0x0e),
|
||||
INACTIVE((byte) 0x0f);
|
||||
|
||||
private byte value;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
|
@ -8,6 +9,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
|
|||
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.action.OmnipodAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType;
|
||||
|
@ -36,20 +38,23 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
|
|||
instance = this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) {
|
||||
if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) {
|
||||
PumpEnactResult result = delegate.pairAndPrime();
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, result.success, (result.success ? null : result.comment));
|
||||
PumpEnactResult result = delegate.pairAndPrime(res -> //
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, res.getResultType().isSuccess(), createCommentForSetupActionResult(res)));
|
||||
if(!result.success) {
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, false, result.comment);
|
||||
}
|
||||
return result;
|
||||
} else if (PodInitActionType.FillCannulaSetBasalProfileWizardStep.equals(podInitActionType)) {
|
||||
// FIXME we need a basal profile here
|
||||
PumpEnactResult result = delegate.insertCannula(profile);
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, result.success, (result.success ? null : result.comment));
|
||||
if (result.success) {
|
||||
PumpEnactResult result = delegate.insertCannula(profile, res -> {
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, res.getResultType().isSuccess(), createCommentForSetupActionResult(res));
|
||||
OmnipodUtil.setPodSessionState(delegate.getPodState());
|
||||
RxBus.INSTANCE.send(new EventOmnipodPumpValuesChanged());
|
||||
});
|
||||
if (!result.success) {
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, false, result.comment);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -75,8 +80,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public PumpEnactResult setBasalProfile(Profile basalProfile) {
|
||||
return delegate.setBasalProfile(basalProfile);
|
||||
|
@ -170,4 +173,18 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
|
|||
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String createCommentForSetupActionResult(SetupActionResult res) {
|
||||
String comment = null;
|
||||
switch(res.getResultType()) {
|
||||
case FAILURE:
|
||||
comment = "Unexpected setup progress: "+ res.getSetupProgress();
|
||||
break;
|
||||
case VERIFICATION_FAILURE:
|
||||
comment = "Verification failed: "+ res.getException().getClass().getSimpleName() +": "+ res.getException().getMessage();
|
||||
break;
|
||||
}
|
||||
return comment;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue