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;
|
package info.nightscout.androidaps.plugins.pump.omnipod.comm;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.Duration;
|
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.Profile;
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair;
|
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.AcknowledgeAlertsAction;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.BolusAction;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.BolusAction;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.CancelDeliveryAction;
|
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.GetPodInfoAction;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.GetStatusAction;
|
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.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.PairAction;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.PrimeAction;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.PrimeAction;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetBasalScheduleAction;
|
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;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
|
|
||||||
public class OmnipodManager {
|
public class OmnipodManager {
|
||||||
|
private static final int SETUP_ACTION_VERIFICATION_TRIES = 3;
|
||||||
|
|
||||||
protected final OmnipodCommunicationService communicationService;
|
protected final OmnipodCommunicationService communicationService;
|
||||||
protected PodSessionState podState;
|
protected PodSessionState podState;
|
||||||
|
|
||||||
|
@ -54,7 +52,37 @@ public class OmnipodManager {
|
||||||
this.podState = podState;
|
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)) {
|
if (podState == null || podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) {
|
||||||
// TODO use string resource
|
// TODO use string resource
|
||||||
return new PumpEnactResult().success(false).enacted(false).comment("Pod should be paired and primed first");
|
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,
|
communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podState,
|
||||||
BasalScheduleMapper.mapProfileToBasalSchedule(profile)));
|
BasalScheduleMapper.mapProfileToBasalSchedule(profile)));
|
||||||
|
|
||||||
executeDelayed(() -> {
|
executeDelayed(() -> verifySetupAction(statusResponse -> InsertCannulaAction.updateCannulaInsertionStatus(podState, statusResponse), //
|
||||||
// TODO improve: repeat get status when it fails and handle unexpected statuses
|
SetupProgress.COMPLETED, resultHandler),
|
||||||
// TODO give user feedback when priming finished (or somehow failed)
|
OmnipodConst.POD_CANNULA_INSERTION_DURATION);
|
||||||
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());
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// TODO distinguish between certain and uncertain failures
|
// TODO distinguish between certain and uncertain failures
|
||||||
// TODO user friendly error messages (string resources)
|
// TODO user friendly error messages (string resources)
|
||||||
|
@ -357,4 +355,35 @@ public class OmnipodManager {
|
||||||
public PodSessionState getPodState() {
|
public PodSessionState getPodState() {
|
||||||
return this.podState;
|
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),
|
TWO_NOT_USED_BUT_IN_33((byte) 0x0b),
|
||||||
THREE_NOT_USED_BUT_IN_33((byte) 0x0c),
|
THREE_NOT_USED_BUT_IN_33((byte) 0x0c),
|
||||||
ERROR_EVENT_LOGGED_SHUTTING_DOWN((byte) 0x0d),
|
ERROR_EVENT_LOGGED_SHUTTING_DOWN((byte) 0x0d),
|
||||||
DELAYED_PRIME((byte) 0x0e),
|
a((byte) 0x0e),
|
||||||
INACTIVE((byte) 0x0f);
|
INACTIVE((byte) 0x0f);
|
||||||
|
|
||||||
private byte value;
|
private byte value;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm;
|
package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.Profile;
|
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.common.data.TempBasalPair;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationService;
|
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.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.comm.action.OmnipodAction;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface;
|
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.PodInfoType;
|
||||||
|
@ -36,20 +38,23 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) {
|
public PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) {
|
||||||
if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) {
|
if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) {
|
||||||
PumpEnactResult result = delegate.pairAndPrime();
|
PumpEnactResult result = delegate.pairAndPrime(res -> //
|
||||||
podInitReceiver.returnInitTaskStatus(podInitActionType, result.success, (result.success ? null : result.comment));
|
podInitReceiver.returnInitTaskStatus(podInitActionType, res.getResultType().isSuccess(), createCommentForSetupActionResult(res)));
|
||||||
|
if(!result.success) {
|
||||||
|
podInitReceiver.returnInitTaskStatus(podInitActionType, false, result.comment);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
} else if (PodInitActionType.FillCannulaSetBasalProfileWizardStep.equals(podInitActionType)) {
|
} else if (PodInitActionType.FillCannulaSetBasalProfileWizardStep.equals(podInitActionType)) {
|
||||||
// FIXME we need a basal profile here
|
PumpEnactResult result = delegate.insertCannula(profile, res -> {
|
||||||
PumpEnactResult result = delegate.insertCannula(profile);
|
podInitReceiver.returnInitTaskStatus(podInitActionType, res.getResultType().isSuccess(), createCommentForSetupActionResult(res));
|
||||||
podInitReceiver.returnInitTaskStatus(podInitActionType, result.success, (result.success ? null : result.comment));
|
|
||||||
if (result.success) {
|
|
||||||
OmnipodUtil.setPodSessionState(delegate.getPodState());
|
OmnipodUtil.setPodSessionState(delegate.getPodState());
|
||||||
RxBus.INSTANCE.send(new EventOmnipodPumpValuesChanged());
|
RxBus.INSTANCE.send(new EventOmnipodPumpValuesChanged());
|
||||||
|
});
|
||||||
|
if (!result.success) {
|
||||||
|
podInitReceiver.returnInitTaskStatus(podInitActionType, false, result.comment);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -75,8 +80,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PumpEnactResult setBasalProfile(Profile basalProfile) {
|
public PumpEnactResult setBasalProfile(Profile basalProfile) {
|
||||||
return delegate.setBasalProfile(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