Re-introduce SetupProgress in order to be able to correctly handle Activation Time Exceeded errors

This commit is contained in:
Bart Sopers 2020-10-17 12:50:08 +02:00
parent 2fcae4b19a
commit b3933e510d
15 changed files with 384 additions and 334 deletions

View file

@ -74,6 +74,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.acti
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.PodInfoRecentPulseLog;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged; import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged;
@ -254,6 +255,13 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
// When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized // When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized
podStateManager.loadPodState(); podStateManager.loadPodState();
// BS @ 2020-10-17 FIXME: for backwards compatibility; remove before release
if (podStateManager.isPodInitialized() &&
podStateManager.getSetupProgress() == SetupProgress.NONE &&
podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS)) {
podStateManager.setSetupProgress(SetupProgress.COMPLETED);
}
lastConnectionTimeMillis = sp.getLong( lastConnectionTimeMillis = sp.getLong(
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
@ -922,7 +930,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
} }
private void initializeAfterRileyLinkConnection() { private void initializeAfterRileyLinkConnection() {
if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.PAIRING_COMPLETED)) { if (podStateManager.getSetupProgress().isAtLeast(SetupProgress.PAIRING_COMPLETED)) {
for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) { for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) {
PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus); PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
if (result.success) { if (result.success) {

View file

@ -5,41 +5,45 @@ import org.joda.time.DateTimeZone;
import java.util.Collections; import java.util.Collections;
import java.util.Random; import java.util.Random;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AssignAddressCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AssignAddressCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
public class AssignAddressAction implements OmnipodAction<VersionResponse> { public class AssignAddressAction implements OmnipodAction<Void> {
private final PodStateManager podStateManager; private final PodStateManager podStateManager;
private final AAPSLogger aapsLogger;
public AssignAddressAction(PodStateManager podStateManager) { public AssignAddressAction(PodStateManager podStateManager, AAPSLogger aapsLogger) {
if (podStateManager == null) { if (podStateManager == null) {
throw new IllegalArgumentException("podStateManager can not be null"); throw new IllegalArgumentException("podStateManager can not be null");
} }
if (aapsLogger == null) {
throw new IllegalArgumentException("Logger can not be null");
}
this.podStateManager = podStateManager; this.podStateManager = podStateManager;
this.aapsLogger = aapsLogger;
} }
@Override @Override
public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
if (!podStateManager.hasPodState()) { if (!podStateManager.hasPodState()) {
podStateManager.initState(generateRandomAddress()); podStateManager.initState(generateRandomAddress());
} }
if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.REMINDER_INITIALIZED)) {
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.getPodProgressStatus());
}
if (podStateManager.getSetupProgress().needsPairing()) {
AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress()); AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress());
OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
Collections.singletonList(assignAddress), podStateManager.getMessageNumber()); Collections.singletonList(assignAddress), podStateManager.getMessageNumber());
try {
VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage, VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage,
OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
@ -52,12 +56,17 @@ public class AssignAddressAction implements OmnipodAction<VersionResponse> {
podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), // podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), //
assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus()); assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus());
} catch (IllegalPacketTypeException ex) {
if (podStateManager.isPodActivationTimeExceeded()) { if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) {
throw new ActivationTimeExceededException(); // When we already assigned the address before, it's possible to only get an ACK here
aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully");
} else {
throw ex;
}
}
} }
return assignAddressResponse; return null;
} }
private static int generateRandomAddress() { private static int generateRandomAddress() {

View file

@ -6,16 +6,15 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
public class InsertCannulaAction implements OmnipodAction<StatusResponse> { public class InsertCannulaAction implements OmnipodAction<Void> {
private final PodStateManager podStateManager; private final PodStateManager podStateManager;
private final BasalSchedule initialBasalSchedule; private final BasalSchedule initialBasalSchedule;
@ -37,31 +36,33 @@ public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
} }
@Override @Override
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_COMPLETED)) {
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); throw new IllegalSetupProgressException(SetupProgress.PRIMING_COMPLETED, podStateManager.getSetupProgress());
} }
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) { if (podStateManager.getSetupProgress().needsBasalSchedule()) {
podStateManager.setBasalSchedule(initialBasalSchedule); podStateManager.setBasalSchedule(initialBasalSchedule);
communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule, communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule,
true, podStateManager.getScheduleOffset(), false)); true, podStateManager.getScheduleOffset(), false));
podStateManager.setSetupProgress(SetupProgress.BASAL_INITIALIZED);
} }
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) { if (podStateManager.getSetupProgress().needsExpirationReminders()) {
communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations())); communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations()));
podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown); podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown);
podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits); podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits);
podStateManager.setSetupProgress(SetupProgress.EXPIRATION_REMINDERS_SET);
return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS,
Duration.standardSeconds(1), false, false));
} else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.INSERTING_CANNULA)) {
// Check status
return communicationService.executeAction(new GetStatusAction(podStateManager));
} else {
throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus());
} }
if (podStateManager.getSetupProgress().needsCannulaInsertion()) {
communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS,
Duration.standardSeconds(1), false, false));
podStateManager.setSetupProgress(SetupProgress.INSERTING_CANNULA);
}
return null;
} }
private List<AlertConfiguration> buildAlertConfigurations() { private List<AlertConfiguration> buildAlertConfigurations() {

View file

@ -1,13 +1,12 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
public class PrimeAction implements OmnipodAction<StatusResponse> { public class PrimeAction implements OmnipodAction<Void> {
private final PrimeService service; private final PrimeService service;
private final PodStateManager podStateManager; private final PodStateManager podStateManager;
@ -24,21 +23,27 @@ public class PrimeAction implements OmnipodAction<StatusResponse> {
} }
@Override @Override
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.PAIRING_COMPLETED)) {
throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); throw new IllegalSetupProgressException(SetupProgress.PAIRING_COMPLETED, podStateManager.getSetupProgress());
} }
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING)) {
if (podStateManager.getSetupProgress().needsDisableTab5Sub16And17()) {
// FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR // FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR
service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager); service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager);
podStateManager.setSetupProgress(SetupProgress.TAB_5_SUB_16_AND_17_DISABLED);
}
if (podStateManager.getSetupProgress().needsSetupReminders()) {
service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager); service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager);
return service.executePrimeBolusCommand(communicationService, podStateManager); podStateManager.setSetupProgress(SetupProgress.SETUP_REMINDERS_SET);
} else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.PRIMING)) { }
// Check status
return communicationService.executeAction(new GetStatusAction(podStateManager)); if (podStateManager.getSetupProgress().needsPriming()) {
} else { service.executePrimeBolusCommand(communicationService, podStateManager);
throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus()); podStateManager.setSetupProgress(SetupProgress.PRIMING);
} }
return null;
} }
} }

View file

@ -4,41 +4,52 @@ import org.joda.time.DateTime;
import java.util.Collections; import java.util.Collections;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
public class SetupPodAction implements OmnipodAction<VersionResponse> { public class SetupPodAction implements OmnipodAction<Void> {
private final PodStateManager podStateManager; private final PodStateManager podStateManager;
private final AAPSLogger aapsLogger;
public SetupPodAction(PodStateManager podStateManager) { public SetupPodAction(PodStateManager podStateManager, AAPSLogger aapsLogger) {
if (podStateManager == null) { if (podStateManager == null) {
throw new IllegalArgumentException("Pod state manager can not be null"); throw new IllegalArgumentException("Pod state manager can not be null");
} }
if (aapsLogger == null) {
throw new IllegalArgumentException("Logger can not be null");
}
this.podStateManager = podStateManager; this.podStateManager = podStateManager;
this.aapsLogger = aapsLogger;
} }
@Override @Override
public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
if (!podStateManager.isPodInitialized() || !podStateManager.getPodProgressStatus().equals(PodProgressStatus.REMINDER_INITIALIZED)) { if (!podStateManager.isPodInitialized()) {
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
} }
if (podStateManager.getSetupProgress().needsPairing()) {
DateTime activationDate = DateTime.now(podStateManager.getTimeZone()); DateTime activationDate = DateTime.now(podStateManager.getTimeZone());
SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate, SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate,
podStateManager.getLot(), podStateManager.getTid()); podStateManager.getLot(), podStateManager.getTid());
OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber()); Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber());
VersionResponse setupPodResponse;
setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, try {
VersionResponse setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager,
message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
if (!setupPodResponse.isSetupPodVersionResponse()) { if (!setupPodResponse.isSetupPodVersionResponse()) {
@ -47,11 +58,18 @@ public class SetupPodAction implements OmnipodAction<VersionResponse> {
if (setupPodResponse.getAddress() != podStateManager.getAddress()) { if (setupPodResponse.getAddress() != podStateManager.getAddress()) {
throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress()); throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress());
} }
} catch (IllegalPacketTypeException ex) {
if (podStateManager.isPodActivationTimeExceeded()) { if (PacketType.ACK.equals(ex.getActual())) {
throw new ActivationTimeExceededException(); // Pod is already configured
aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring");
} else {
throw ex;
}
} }
return setupPodResponse; podStateManager.setSetupProgress(SetupProgress.PAIRING_COMPLETED);
}
return null;
} }
} }

View file

@ -0,0 +1,66 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition;
public enum SetupProgress {
NONE,
PAIRING_COMPLETED,
TAB_5_SUB_16_AND_17_DISABLED,
SETUP_REMINDERS_SET,
PRIMING,
PRIMING_COMPLETED,
BASAL_INITIALIZED,
EXPIRATION_REMINDERS_SET,
INSERTING_CANNULA,
COMPLETED;
public boolean needsPairing() {
return this == NONE;
}
public boolean needsDisableTab5Sub16And17() {
return this == PAIRING_COMPLETED;
}
public boolean needsSetupReminders() {
return this == TAB_5_SUB_16_AND_17_DISABLED;
}
public boolean needsPriming() {
return this == SETUP_REMINDERS_SET;
}
public boolean needsPrimingVerification() {
return this == PRIMING;
}
public boolean needsBasalSchedule() {
return this == PRIMING_COMPLETED;
}
public boolean needsExpirationReminders() {
return this == BASAL_INITIALIZED;
}
public boolean needsCannulaInsertion() {
return this == EXPIRATION_REMINDERS_SET;
}
public boolean needsCannulaInsertionVerification() {
return this == INSERTING_CANNULA;
}
public boolean isCompleted() {
return this == COMPLETED;
}
public boolean isBefore(SetupProgress other) {
return ordinal() < other.ordinal();
}
public boolean isAtLeast(SetupProgress other) {
return ordinal() >= other.ordinal();
}
public boolean isAfter(SetupProgress other) {
return ordinal() > other.ordinal();
}
}

View file

@ -9,7 +9,7 @@ public class IllegalPodProgressException extends OmnipodException {
private final PodProgressStatus actual; private final PodProgressStatus actual;
public IllegalPodProgressException(PodProgressStatus expected, PodProgressStatus actual) { public IllegalPodProgressException(PodProgressStatus expected, PodProgressStatus actual) {
super(String.format(Locale.getDefault(), "Illegal setup state: %s, expected: %s", actual, expected), true); super(String.format(Locale.getDefault(), "Illegal Pod progress: %s, expected: %s", actual, expected), true);
this.expected = expected; this.expected = expected;
this.actual = actual; this.actual = actual;
} }

View file

@ -0,0 +1,24 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception;
import java.util.Locale;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
public class IllegalSetupProgressException extends OmnipodException {
private final SetupProgress expected;
private final SetupProgress actual;
public IllegalSetupProgressException(SetupProgress expected, SetupProgress actual) {
super(String.format(Locale.getDefault(), "Illegal setup progress: %s, expected: %s", actual, expected), true);
this.expected = expected;
this.actual = actual;
}
public SetupProgress getExpected() {
return expected;
}
public SetupProgress getActual() {
return actual;
}
}

View file

@ -36,16 +36,15 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepTyp
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule;
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.CommandFailedAfterChangingDeliveryStatusException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; 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.PodFaultException;
@ -89,45 +88,21 @@ public class OmnipodManager {
} }
public synchronized Single<Boolean> pairAndPrime() { public synchronized Single<Boolean> pairAndPrime() {
if (podStateManager.isPodActivationTimeExceeded()) { if (podStateManager.isPodInitialized()) {
throw new ActivationTimeExceededException(); if (podStateManager.getSetupProgress().isAfter(SetupProgress.PRIMING)) {
}
if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.PRIMING)) {
return Single.just(true); return Single.just(true);
} }
if (podStateManager.getSetupProgress().needsPrimingVerification()) {
return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, SetupProgress.PRIMING_COMPLETED));
}
}
logStartingCommandExecution("pairAndPrime");
try {
// Always send both 0x07 and 0x03 on retries // Always send both 0x07 and 0x03 on retries
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.PAIRING_COMPLETED)) {
try {
communicationService.executeAction( communicationService.executeAction(
new AssignAddressAction(podStateManager)); new AssignAddressAction(podStateManager, aapsLogger));
} catch (IllegalPacketTypeException ex) {
if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) {
// When we already assigned the address before, it's possible to only get an ACK here
aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully");
} else {
throw ex;
}
}
try { communicationService.executeAction(new SetupPodAction(podStateManager, aapsLogger));
communicationService.executeAction(new SetupPodAction(podStateManager));
} catch (IllegalPacketTypeException ex) {
if (PacketType.ACK.equals(ex.getActual())) {
// Pod is already configured
aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring");
}
}
} else {
// Make sure we have an up to date PodProgressStatus
getPodStatus();
if (podStateManager.isPodActivationTimeExceeded()) {
throw new ActivationTimeExceededException();
}
} }
communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager)); communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager));
@ -135,43 +110,32 @@ public class OmnipodManager {
long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis(); long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis();
return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) //
.map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED)) // .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, SetupProgress.PRIMING_COMPLETED)) //
.subscribeOn(Schedulers.io()); .subscribeOn(Schedulers.io());
} finally {
logCommandExecutionFinished("pairAndPrime");
}
} }
public synchronized Single<Boolean> insertCannula( public synchronized Single<Boolean> insertCannula(
BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) { BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) {
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_COMPLETED)) {
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, !podStateManager.isPodInitialized() ? null : podStateManager.getPodProgressStatus()); throw new IllegalSetupProgressException(SetupProgress.PRIMING_COMPLETED, podStateManager.getSetupProgress());
} }
logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]"); if (podStateManager.isPodInitialized()) {
if (podStateManager.getSetupProgress().isCompleted()) {
try {
// Make sure we have the latest PodProgressStatus
getPodStatus();
if (podStateManager.isPodActivationTimeExceeded()) {
throw new ActivationTimeExceededException();
}
if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.INSERTING_CANNULA)) {
return Single.just(true); return Single.just(true);
} }
if (podStateManager.getSetupProgress().needsCannulaInsertionVerification()) {
return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, SetupProgress.COMPLETED));
}
}
communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits)); communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits));
long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis(); long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis();
return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) //
.map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS)) // .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, SetupProgress.COMPLETED)) //
.subscribeOn(Schedulers.io()); .subscribeOn(Schedulers.io());
} finally {
logCommandExecutionFinished("insertCannula");
}
} }
public synchronized StatusResponse getPodStatus() { public synchronized StatusResponse getPodStatus() {
@ -179,49 +143,29 @@ public class OmnipodManager {
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null); throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
} }
logStartingCommandExecution("getPodStatus");
try {
return communicationService.executeAction(new GetStatusAction(podStateManager)); return communicationService.executeAction(new GetStatusAction(podStateManager));
} finally {
logCommandExecutionFinished("getPodStatus");
}
} }
public synchronized PodInfoResponse getPodInfo(PodInfoType podInfoType) { public synchronized PodInfoResponse getPodInfo(PodInfoType podInfoType) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("getPodInfo");
try {
return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType)); return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType));
} finally {
logCommandExecutionFinished("getPodInfo");
}
} }
public synchronized StatusResponse configureAlerts(List<AlertConfiguration> alertConfigurations) { public synchronized StatusResponse configureAlerts(List<AlertConfiguration> alertConfigurations) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("configureAlerts");
try {
StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations))); StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations)));
ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations); ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations);
return statusResponse; return statusResponse;
} finally {
logCommandExecutionFinished("configureAlerts");
}
} }
public synchronized StatusResponse acknowledgeAlerts() { public synchronized StatusResponse acknowledgeAlerts() {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("acknowledgeAlerts");
try {
return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts()))); return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts())));
} finally {
logCommandExecutionFinished("acknowledgeAlerts");
}
} }
// CAUTION: cancels all delivery // CAUTION: cancels all delivery
@ -229,9 +173,6 @@ public class OmnipodManager {
public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) { public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("setBasalSchedule [basalSchedule=" + schedule + ", acknowledgementBeep=" + acknowledgementBeep + "]");
try {
boolean wasSuspended = podStateManager.isSuspended(); boolean wasSuspended = podStateManager.isSuspended();
if (!wasSuspended) { if (!wasSuspended) {
suspendDelivery(acknowledgementBeep); suspendDelivery(acknowledgementBeep);
@ -260,22 +201,14 @@ public class OmnipodManager {
throw ex; throw ex;
} }
} }
} finally {
logCommandExecutionFinished("setBasalSchedule");
}
} }
// 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 // 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) { public synchronized void setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("setTemporaryBasal [rate=" + rate + ", duration=" + duration + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
boolean cancelCurrentTbr = podStateManager.isTempBasalRunning(); boolean cancelCurrentTbr = podStateManager.isTempBasalRunning();
try {
if (cancelCurrentTbr) { if (cancelCurrentTbr) {
try { try {
cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep); cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep);
@ -333,9 +266,6 @@ public class OmnipodManager {
throw ex2; throw ex2;
} }
} }
} finally {
logCommandExecutionFinished("setTemporaryBasal");
}
} }
public synchronized void cancelTemporaryBasal(boolean acknowledgementBeep) { public synchronized void cancelTemporaryBasal(boolean acknowledgementBeep) {
@ -361,17 +291,11 @@ public class OmnipodManager {
private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) { private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("cancelDelivery [deliveryTypes=" + deliveryTypes + ", acknowledgementBeep=" + acknowledgementBeep + "]");
try {
return executeAndVerify(() -> { return executeAndVerify(() -> {
StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep)); StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep));
aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString()); aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
return statusResponse; return statusResponse;
}); });
} finally {
logCommandExecutionFinished("cancelDelivery");
}
} }
// Returns a SingleSubject that returns when the bolus has finished. // Returns a SingleSubject that returns when the bolus has finished.
@ -380,8 +304,6 @@ public class OmnipodManager {
public synchronized BolusCommandResult bolus(Double units, boolean acknowledgementBeep, boolean completionBeep, BiConsumer<Double, Integer> progressIndicationConsumer) { public synchronized BolusCommandResult bolus(Double units, boolean acknowledgementBeep, boolean completionBeep, BiConsumer<Double, Integer> progressIndicationConsumer) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("bolus [units=" + units + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
bolusCommandExecutionSubject = SingleSubject.create(); bolusCommandExecutionSubject = SingleSubject.create();
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS; CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
@ -467,8 +389,6 @@ public class OmnipodManager {
}) })
.subscribe()); .subscribe());
logCommandExecutionFinished("bolus");
return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject); return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject);
} }
@ -480,16 +400,12 @@ public class OmnipodManager {
throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus()); throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus());
} }
logStartingCommandExecution("cancelBolus [acknowledgementBeep=" + acknowledgementBeep + "]");
try { try {
StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep); StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep);
discardActiveBolusData(statusResponse.getBolusNotDelivered()); discardActiveBolusData(statusResponse.getBolusNotDelivered());
} catch (PodFaultException ex) { } catch (PodFaultException ex) {
discardActiveBolusData(ex.getDetailedStatus().getBolusNotDelivered()); discardActiveBolusData(ex.getDetailedStatus().getBolusNotDelivered());
throw ex; throw ex;
} finally {
logCommandExecutionFinished("cancelBolus");
} }
} }
} }
@ -507,7 +423,6 @@ public class OmnipodManager {
public synchronized void suspendDelivery(boolean acknowledgementBeep) { public synchronized void suspendDelivery(boolean acknowledgementBeep) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("suspendDelivery");
try { try {
cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep); cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep);
@ -521,8 +436,6 @@ public class OmnipodManager {
ex.setCertainFailure(true); ex.setCertainFailure(true);
throw ex; throw ex;
} }
} finally {
logCommandExecutionFinished("suspendDelivery");
} }
} }
@ -531,9 +444,6 @@ public class OmnipodManager {
public synchronized void setTime(boolean acknowledgementBeeps) { public synchronized void setTime(boolean acknowledgementBeeps) {
assertReadyForDelivery(); assertReadyForDelivery();
logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]");
try {
DateTimeZone oldTimeZone = podStateManager.getTimeZone(); DateTimeZone oldTimeZone = podStateManager.getTimeZone();
try { try {
@ -548,9 +458,6 @@ public class OmnipodManager {
} }
podStateManager.updateActivatedAt(); podStateManager.updateActivatedAt();
} finally {
logCommandExecutionFinished("setTime");
}
} }
public synchronized void deactivatePod() { public synchronized void deactivatePod() {
@ -558,8 +465,6 @@ public class OmnipodManager {
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null); throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
} }
logStartingCommandExecution("deactivatePod");
// Try to get pulse log for diagnostics // Try to get pulse log for diagnostics
try { try {
PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG)); PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG));
@ -574,8 +479,6 @@ public class OmnipodManager {
communicationService.executeAction(new DeactivatePodAction(podStateManager, true)); communicationService.executeAction(new DeactivatePodAction(podStateManager, true));
} catch (PodFaultException ex) { } catch (PodFaultException ex) {
aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex); aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex);
} finally {
logCommandExecutionFinished("deactivatePod");
} }
podStateManager.discardState(); podStateManager.discardState();
@ -605,7 +508,6 @@ public class OmnipodManager {
// Only works for commands with nonce resyncable message blocks // Only works for commands with nonce resyncable message blocks
private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) { private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) {
logStartingCommandExecution("verifyCommand");
try { try {
return supplier.get(); return supplier.get();
} catch (OmnipodException originalException) { } catch (OmnipodException originalException) {
@ -629,8 +531,6 @@ public class OmnipodManager {
throw originalException; throw originalException;
} }
} }
} finally {
logCommandExecutionFinished("verifyCommand");
} }
} }
@ -645,7 +545,7 @@ public class OmnipodManager {
* @return true if the Pod's progress status matches the expected status, otherwise false * @return true if the Pod's progress status matches the expected status, otherwise false
* @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails * @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails
*/ */
private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus) { private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus, SetupProgress setupProgress) {
Boolean result = null; Boolean result = null;
Throwable lastException = null; Throwable lastException = null;
@ -654,6 +554,7 @@ public class OmnipodManager {
StatusResponse statusResponse = getPodStatus(); StatusResponse statusResponse = getPodStatus();
if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) { if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) {
podStateManager.setSetupProgress(setupProgress);
return true; return true;
} else { } else {
result = false; result = false;
@ -694,14 +595,6 @@ public class OmnipodManager {
throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause); throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause);
} }
private void logStartingCommandExecution(String action) {
aapsLogger.debug(LTag.PUMPCOMM, "Starting command execution for action: " + action);
}
private void logCommandExecutionFinished(String action) {
aapsLogger.debug(LTag.PUMPCOMM, "Command execution finished for action: " + action);
}
private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) { private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) {
if (!podStateManager.isPodActivationCompleted()) { if (!podStateManager.isPodActivationCompleted()) {
// No basal or temp basal is active yet // No basal or temp basal is active yet

View file

@ -16,6 +16,7 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
@ -31,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.Firmwar
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule;
// TODO add nullchecks on some setters // TODO add nullchecks on some setters
@ -80,7 +82,7 @@ public abstract class PodStateManager {
* @return true if we have a Pod state and the Pod activation has been completed. The pod could also be dead at this point * @return true if we have a Pod state and the Pod activation has been completed. The pod could also be dead at this point
*/ */
public final boolean isPodActivationCompleted() { public final boolean isPodActivationCompleted() {
return isPodInitialized() && podState.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS) && !isPodActivationTimeExceeded(); return getSetupProgress().isCompleted();
} }
/** /**
@ -335,6 +337,17 @@ public abstract class PodStateManager {
return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())).plus(OmnipodConstants.NOMINAL_POD_LIFE); return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())).plus(OmnipodConstants.NOMINAL_POD_LIFE);
} }
public final SetupProgress getSetupProgress() {
if (hasPodState()) {
return Optional.ofNullable(podState.getSetupProgress()).orElse(SetupProgress.NONE);
}
return SetupProgress.NONE;
}
public final void setSetupProgress(SetupProgress setupProgress) {
setAndStore(() -> podState.setSetupProgress(setupProgress));
}
public final PodProgressStatus getPodProgressStatus() { public final PodProgressStatus getPodProgressStatus() {
return getSafe(() -> podState.getPodProgressStatus()); return getSafe(() -> podState.getPodProgressStatus());
} }
@ -642,6 +655,7 @@ public abstract class PodStateManager {
private Integer totalTicksDelivered; private Integer totalTicksDelivered;
private boolean suspended; private boolean suspended;
private NonceState nonceState; private NonceState nonceState;
private SetupProgress setupProgress = SetupProgress.NONE;
private PodProgressStatus podProgressStatus; private PodProgressStatus podProgressStatus;
private DeliveryStatus lastDeliveryStatus; private DeliveryStatus lastDeliveryStatus;
private AlertSet activeAlerts; private AlertSet activeAlerts;
@ -810,6 +824,14 @@ public abstract class PodStateManager {
this.nonceState = nonceState; this.nonceState = nonceState;
} }
SetupProgress getSetupProgress() {
return setupProgress;
}
void setSetupProgress(SetupProgress setupProgress) {
this.setupProgress = setupProgress;
}
PodProgressStatus getPodProgressStatus() { PodProgressStatus getPodProgressStatus() {
return podProgressStatus; return podProgressStatus;
} }
@ -941,11 +963,12 @@ public abstract class PodStateManager {
", timeZone=" + timeZone + ", timeZone=" + timeZone +
", activatedAt=" + activatedAt + ", activatedAt=" + activatedAt +
", timeActive=" + timeActive + ", timeActive=" + timeActive +
", faultEvent=" + faultEventCode + ", faultEventCode=" + faultEventCode +
", reservoirLevel=" + reservoirLevel + ", reservoirLevel=" + reservoirLevel +
", totalTicksDelivered=" + totalTicksDelivered + ", totalTicksDelivered=" + totalTicksDelivered +
", suspended=" + suspended + ", suspended=" + suspended +
", nonceState=" + nonceState + ", nonceState=" + nonceState +
", setupProgress=" + setupProgress +
", podProgressStatus=" + podProgressStatus + ", podProgressStatus=" + podProgressStatus +
", lastDeliveryStatus=" + lastDeliveryStatus + ", lastDeliveryStatus=" + lastDeliveryStatus +
", activeAlerts=" + activeAlerts + ", activeAlerts=" + activeAlerts +

View file

@ -62,6 +62,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalM
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
@ -770,7 +771,8 @@ public class AapsOmnipodManager {
comment = getStringResource(R.string.omnipod_error_crc_mismatch); comment = getStringResource(R.string.omnipod_error_crc_mismatch);
} else if (ex instanceof IllegalPacketTypeException) { } else if (ex instanceof IllegalPacketTypeException) {
comment = getStringResource(R.string.omnipod_error_invalid_packet_type); comment = getStringResource(R.string.omnipod_error_invalid_packet_type);
} else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalDeliveryStatusException) { } else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalSetupProgressException ||
ex instanceof IllegalDeliveryStatusException) {
comment = getStringResource(R.string.omnipod_error_invalid_progress_state); comment = getStringResource(R.string.omnipod_error_invalid_progress_state);
} else if (ex instanceof IllegalVersionResponseTypeException) { } else if (ex instanceof IllegalVersionResponseTypeException) {
comment = getStringResource(R.string.omnipod_error_invalid_response); comment = getStringResource(R.string.omnipod_error_invalid_response);

View file

@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.R import info.nightscout.androidaps.plugins.pump.omnipod.R
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
@ -345,9 +346,7 @@ class OmnipodOverviewFragment : DaggerFragment() {
if (!podStateManager.isPodInitialized) { if (!podStateManager.isPodInitialized) {
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
} else { } else {
if (podStateManager.isPodActivationTimeExceeded) { if (podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_COMPLETED)) {
resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded)
} else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
} else { } else {
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion) resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion)
@ -454,7 +453,7 @@ class OmnipodOverviewFragment : DaggerFragment() {
} }
private fun updateRefreshStatusButton() { private fun updateRefreshStatusButton() {
omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.podProgressStatus.isAtLeast(PodProgressStatus.PAIRING_COMPLETED) omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED)
&& rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
} }

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.omnipod.R import info.nightscout.androidaps.plugins.pump.omnipod.R
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
@ -93,8 +94,8 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
omnipod_pod_management_waiting_for_rl_layout.visibility = (!rileyLinkServiceData.rileyLinkServiceState.isReady).toVisibility() omnipod_pod_management_waiting_for_rl_layout.visibility = (!rileyLinkServiceData.rileyLinkServiceState.isReady).toVisibility()
if (rileyLinkServiceData.rileyLinkServiceState.isReady) { if (rileyLinkServiceData.rileyLinkServiceState.isReady) {
omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted && !podStateManager.isPodActivationTimeExceeded omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted
omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.isPodInitialized omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED)
if (discardButtonEnabled) { if (discardButtonEnabled) {
omnipod_pod_management_button_discard_pod.isEnabled = true omnipod_pod_management_button_discard_pod.isEnabled = true
} }

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation
import android.os.Bundle import android.os.Bundle
import androidx.annotation.IdRes import androidx.annotation.IdRes
import info.nightscout.androidaps.plugins.pump.omnipod.R import info.nightscout.androidaps.plugins.pump.omnipod.R
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase
import javax.inject.Inject import javax.inject.Inject
@ -25,7 +25,7 @@ class PodActivationWizardActivity : OmnipodWizardActivityBase() {
setContentView(R.layout.omnipod_pod_activation_wizard_activity) setContentView(R.layout.omnipod_pod_activation_wizard_activity)
startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment) startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment)
?: if (!podStateManager.isPodInitialized || podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) { ?: if (!podStateManager.isPodInitialized || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_COMPLETED)) {
R.id.fillPodInfoFragment R.id.fillPodInfoFragment
} else { } else {
R.id.attachPodInfoFragment R.id.attachPodInfoFragment

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.fra
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.fragment.ActionFragmentBase import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.fragment.ActionFragmentBase
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity
@ -25,7 +26,7 @@ abstract class PodActivationActionFragmentBase : ActionFragmentBase() {
} }
override fun onActionFailure() { override fun onActionFailure() {
if (podStateManager.isPodActivationTimeExceeded) { if (podStateManager.isPodActivationTimeExceeded && podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED)) {
omnipod_wizard_button_retry.visibility = View.GONE omnipod_wizard_button_retry.visibility = View.GONE
omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE
} }