- Improve Pod state accuracy for basal profile & TBR

- Add certainty info about last bolus and temp basal to Pod state and display in OmnipodFragment
- Improve user notifications of delivery errors# Please enter the commit message for your changes. Lines starting
This commit is contained in:
Bart Sopers 2020-09-02 20:48:56 +02:00
parent 6b027b8360
commit b1abc55def
8 changed files with 245 additions and 139 deletions

View file

@ -37,6 +37,7 @@ public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
} }
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) { if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) {
podStateManager.setBasalSchedule(initialBasalSchedule);
service.programInitialBasalSchedule(communicationService, podStateManager, initialBasalSchedule); service.programInitialBasalSchedule(communicationService, podStateManager, initialBasalSchedule);
} }

View file

@ -46,8 +46,6 @@ public class SetBasalScheduleAction implements OmnipodAction<StatusResponse> {
OmnipodMessage basalMessage = new OmnipodMessage(podStateManager.getAddress(), Arrays.asList(setBasal, extraCommand), OmnipodMessage basalMessage = new OmnipodMessage(podStateManager.getAddress(), Arrays.asList(setBasal, extraCommand),
podStateManager.getMessageNumber()); podStateManager.getMessageNumber());
StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, basalMessage); return communicationService.exchangeMessages(StatusResponse.class, podStateManager, basalMessage);
podStateManager.setBasalSchedule(basalSchedule);
return statusResponse;
} }
} }

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
import java.util.Arrays; import java.util.Arrays;
@ -11,7 +10,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetInsulinScheduleCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetInsulinScheduleCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.TempBasalExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.TempBasalExtraCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException;
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;
@ -45,8 +43,6 @@ public class SetTempBasalAction implements OmnipodAction<StatusResponse> {
new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO));
OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber()); OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber());
StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, message); return communicationService.exchangeMessages(StatusResponse.class, podStateManager, message);
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration);
return statusResponse;
} }
} }

View file

@ -212,6 +212,7 @@ public class OmnipodManager {
try { try {
executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule, executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule,
false, podStateManager.getScheduleOffset(), acknowledgementBeep))); false, podStateManager.getScheduleOffset(), acknowledgementBeep)));
podStateManager.setBasalSchedule(schedule);
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
if (ex.isCertainFailure()) { if (ex.isCertainFailure()) {
if (!wasSuspended) { if (!wasSuspended) {
@ -221,7 +222,9 @@ public class OmnipodManager {
} }
// verifyDeliveryStatus will throw an exception if verification fails // verifyDeliveryStatus will throw an exception if verification fails
if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { if (verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) {
podStateManager.setBasalSchedule(schedule);
} else {
if (!wasSuspended) { if (!wasSuspended) {
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex);
} }
@ -262,6 +265,7 @@ public class OmnipodManager {
try { try {
executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction(
podStateManager, rate, duration, acknowledgementBeep, completionBeep))); podStateManager, rate, duration, acknowledgementBeep, completionBeep)));
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true);
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
if (ex.isCertainFailure()) { if (ex.isCertainFailure()) {
if (cancelCurrentTbr) { if (cancelCurrentTbr) {
@ -271,7 +275,10 @@ public class OmnipodManager {
} }
// verifyDeliveryStatus will throw an exception if verification fails // verifyDeliveryStatus will throw an exception if verification fails
if (!verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) { try {
if (verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) {
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true);
} else {
if (cancelCurrentTbr) { if (cancelCurrentTbr) {
throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex);
} }
@ -279,6 +286,15 @@ public class OmnipodManager {
ex.setCertainFailure(true); ex.setCertainFailure(true);
throw ex; throw ex;
} }
} catch (OmnipodException ex2) {
if (!ex2.isCertainFailure()) {
// We're not sure that setting the new TBR failed, so we assume that it succeeded
// If it didn't, PodStateManager.updateFromResponse() will fix the state
// upon receiving the next StatusResponse
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, false);
}
throw ex2;
}
} }
} finally { } finally {
logCommandExecutionFinished("setTemporaryBasal"); logCommandExecutionFinished("setTemporaryBasal");
@ -331,15 +347,16 @@ public class OmnipodManager {
commandDeliveryStatus = CommandDeliveryStatus.UNCERTAIN_FAILURE; commandDeliveryStatus = CommandDeliveryStatus.UNCERTAIN_FAILURE;
} }
Duration bolusDuration = calculateBolusDuration(units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE); DateTime estimatedBolusStartDate = DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
Duration estimatedRemainingBolusDuration = bolusDuration.minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); Duration estimatedBolusDuration = calculateBolusDuration(units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE);
Duration estimatedRemainingBolusDuration = estimatedBolusDuration.minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
DateTime startDate = DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); podStateManager.setLastBolus(estimatedBolusStartDate, units, estimatedBolusDuration, commandDeliveryStatus == CommandDeliveryStatus.SUCCESS);
podStateManager.setLastBolus(startDate, units, estimatedRemainingBolusDuration);
CompositeDisposable disposables = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
if (progressIndicationConsumer != null) { if (progressIndicationConsumer != null) {
int numberOfProgressReports = Math.max(20, Math.min(100, (int) Math.ceil(units) * 10)); int numberOfProgressReports = Math.max(20, Math.min(100, (int) Math.ceil(units) * 10));
long progressReportInterval = estimatedRemainingBolusDuration.getMillis() / numberOfProgressReports; long progressReportInterval = estimatedRemainingBolusDuration.getMillis() / numberOfProgressReports;
@ -355,7 +372,7 @@ public class OmnipodManager {
SingleSubject<BolusDeliveryResult> bolusCompletionSubject = SingleSubject.create(); SingleSubject<BolusDeliveryResult> bolusCompletionSubject = SingleSubject.create();
synchronized (bolusDataMutex) { synchronized (bolusDataMutex) {
activeBolusData = new ActiveBolusData(units, startDate, bolusCompletionSubject, disposables); activeBolusData = new ActiveBolusData(units, estimatedBolusStartDate, commandDeliveryStatus, bolusCompletionSubject, disposables);
} }
// Return successful command execution AFTER storing activeBolusData // Return successful command execution AFTER storing activeBolusData
@ -380,7 +397,7 @@ public class OmnipodManager {
break; break;
} }
} catch (PodFaultException ex) { } catch (PodFaultException ex) {
// Substract units not delivered in case of a Pod failure // Subtract units not delivered in case of a Pod failure
bolusNotDelivered = ex.getFaultEvent().getBolusNotDelivered(); bolusNotDelivered = ex.getFaultEvent().getBolusNotDelivered();
aapsLogger.debug(LTag.PUMPCOMM, "Caught PodFaultException in bolus completion verification", ex); aapsLogger.debug(LTag.PUMPCOMM, "Caught PodFaultException in bolus completion verification", ex);
@ -428,7 +445,7 @@ public class OmnipodManager {
private void discardActiveBolusData(double bolusNotDelivered) { private void discardActiveBolusData(double bolusNotDelivered) {
synchronized (bolusDataMutex) { synchronized (bolusDataMutex) {
double unitsDelivered = activeBolusData.getUnits() - bolusNotDelivered; double unitsDelivered = activeBolusData.getUnits() - bolusNotDelivered;
podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered, new Duration(activeBolusData.getStartDate(), DateTime.now())); podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered, new Duration(activeBolusData.getStartDate(), DateTime.now()), activeBolusData.getCommandDeliveryStatus() == CommandDeliveryStatus.SUCCESS);
activeBolusData.getDisposables().dispose(); activeBolusData.getDisposables().dispose();
activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(unitsDelivered)); activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(unitsDelivered));
activeBolusData = null; activeBolusData = null;
@ -465,8 +482,6 @@ public class OmnipodManager {
logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]"); logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]");
try { try {
suspendDelivery(acknowledgementBeeps);
DateTimeZone oldTimeZone = podStateManager.getTimeZone(); DateTimeZone oldTimeZone = podStateManager.getTimeZone();
try { try {
@ -476,20 +491,8 @@ public class OmnipodManager {
setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps); setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps);
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
podStateManager.setTimeZone(oldTimeZone); podStateManager.setTimeZone(oldTimeZone);
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but resuming did not", ex); throw ex;
}
try {
// verifyDeliveryStatus will throw an exception if verification fails
if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) {
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but resuming did not", ex);
}
} catch (Exception ex2) {
podStateManager.setTimeZone(oldTimeZone);
throw ex2;
}
} }
} finally { } finally {
logCommandExecutionFinished("setTime"); logCommandExecutionFinished("setTime");
@ -620,13 +623,14 @@ public class OmnipodManager {
*/ */
private boolean verifyDeliveryStatus(DeliveryStatus expectedStatus, Throwable verificationCause) { private boolean verifyDeliveryStatus(DeliveryStatus expectedStatus, Throwable verificationCause) {
aapsLogger.debug(LTag.PUMPCOMM, "Attempting to verify delivery status (expected={})", expectedStatus); aapsLogger.debug(LTag.PUMPCOMM, "Attempting to verify delivery status (expected={})", expectedStatus);
for (int i = 0; 2 > i; i++) { for (int i = 0; 3 > i; i++) {
try { try {
StatusResponse podStatus = getPodStatus(); StatusResponse podStatus = getPodStatus();
aapsLogger.debug(LTag.PUMPCOMM, "Resolved delivery status (expected={}, actual={})", expectedStatus, podStatus.getDeliveryStatus()); aapsLogger.debug(LTag.PUMPCOMM, "Resolved delivery status (expected={}, actual={})", expectedStatus, podStatus.getDeliveryStatus());
return podStatus.getDeliveryStatus().equals(expectedStatus); return podStatus.getDeliveryStatus().equals(expectedStatus);
} catch (Exception ignored) { } catch (Exception ex) {
// ignore and try to continue aapsLogger.debug(LTag.PUMPCOMM, "Ignoring exception thrown in getPodStatus() during attempt to verify delivery status: {}: {}",
ex.getClass().getSimpleName(), ex.getMessage());
} }
} }
aapsLogger.warn(LTag.PUMPCOMM, "Failed to verify delivery status"); aapsLogger.warn(LTag.PUMPCOMM, "Failed to verify delivery status");
@ -694,12 +698,14 @@ public class OmnipodManager {
private static class ActiveBolusData { private static class ActiveBolusData {
private final double units; private final double units;
private final DateTime startDate; private final DateTime startDate;
private final CommandDeliveryStatus commandDeliveryStatus;
private final SingleSubject<BolusDeliveryResult> bolusCompletionSubject; private final SingleSubject<BolusDeliveryResult> bolusCompletionSubject;
private final CompositeDisposable disposables; private final CompositeDisposable disposables;
private ActiveBolusData(double units, DateTime startDate, SingleSubject<BolusDeliveryResult> bolusCompletionSubject, CompositeDisposable disposables) { private ActiveBolusData(double units, DateTime startDate, CommandDeliveryStatus commandDeliveryStatus, SingleSubject<BolusDeliveryResult> bolusCompletionSubject, CompositeDisposable disposables) {
this.units = units; this.units = units;
this.startDate = startDate; this.startDate = startDate;
this.commandDeliveryStatus = commandDeliveryStatus;
this.bolusCompletionSubject = bolusCompletionSubject; this.bolusCompletionSubject = bolusCompletionSubject;
this.disposables = disposables; this.disposables = disposables;
} }
@ -712,6 +718,10 @@ public class OmnipodManager {
return startDate; return startDate;
} }
CommandDeliveryStatus getCommandDeliveryStatus() {
return commandDeliveryStatus;
}
CompositeDisposable getDisposables() { CompositeDisposable getDisposables() {
return disposables; return disposables;
} }

View file

@ -357,14 +357,24 @@ public abstract class PodStateManager {
return getSafe(() -> podState.getLastBolusDuration()); return getSafe(() -> podState.getLastBolusDuration());
} }
public final void setLastBolus(DateTime startTime, double amount, Duration duration) { public final boolean isLastBolusCertain() {
Boolean certain = getSafe(() -> podState.isLastBolusCertain());
return certain == null || certain;
}
public final void setLastBolus(DateTime startTime, double amount, Duration duration, boolean certain) {
setAndStore(() -> { setAndStore(() -> {
podState.setLastBolusStartTime(startTime); podState.setLastBolusStartTime(startTime);
podState.setLastBolusAmount(amount); podState.setLastBolusAmount(amount);
podState.setLastBolusDuration(duration); podState.setLastBolusDuration(duration);
podState.setLastBolusCertain(certain);
}); });
} }
public final boolean hasLastBolus() {
return getLastBolusAmount() != null && getLastBolusDuration() != null && getLastBolusStartTime() != null;
}
public final DateTime getTempBasalStartTime() { public final DateTime getTempBasalStartTime() {
return getSafe(() -> podState.getTempBasalStartTime()); return getSafe(() -> podState.getTempBasalStartTime());
} }
@ -377,11 +387,16 @@ public abstract class PodStateManager {
return getSafe(() -> podState.getTempBasalDuration()); return getSafe(() -> podState.getTempBasalDuration());
} }
public final void setTempBasal(DateTime startTime, Double amount, Duration duration) { public final boolean isTempBasalCertain() {
setTempBasal(startTime, amount, duration, true); Boolean certain = getSafe(() -> podState.isTempBasalCertain());
return certain == null || certain;
} }
public final void setTempBasal(DateTime startTime, Double amount, Duration duration, boolean store) { public final void setTempBasal(DateTime startTime, Double amount, Duration duration, boolean certain) {
setTempBasal(startTime, amount, duration, certain, true);
}
public final void setTempBasal(DateTime startTime, Double amount, Duration duration, Boolean certain, boolean store) {
DateTime currentStartTime = getTempBasalStartTime(); DateTime currentStartTime = getTempBasalStartTime();
Double currentAmount = getTempBasalAmount(); Double currentAmount = getTempBasalAmount();
Duration currentDuration = getTempBasalDuration(); Duration currentDuration = getTempBasalDuration();
@ -390,6 +405,7 @@ public abstract class PodStateManager {
podState.setTempBasalStartTime(startTime); podState.setTempBasalStartTime(startTime);
podState.setTempBasalAmount(amount); podState.setTempBasalAmount(amount);
podState.setTempBasalDuration(duration); podState.setTempBasalDuration(duration);
podState.setTempBasalCertain(certain);
}; };
if (store) { if (store) {
@ -401,10 +417,26 @@ public abstract class PodStateManager {
} }
} }
/**
* @return true when a Temp Basal is stored in the Pod Stated
* Please note that this could also be an expired Temp Basal. For an indication on whether or not
* a temp basal is actually running, use {@link #isTempBasalRunning() isTempBasalRunning()}
*/
public final boolean hasTempBasal() { public final boolean hasTempBasal() {
return getTempBasalAmount() != null && getTempBasalDuration() != null && getTempBasalStartTime() != null; return getTempBasalAmount() != null && getTempBasalDuration() != null && getTempBasalStartTime() != null;
} }
/**
* @return true when a Temp Basal is stored in the Pod Stated and this temp basal is currently running (based on start time and duration)
*/
public final boolean isTempBasalRunning() {
if (hasTempBasal()) {
DateTime tempBasalEndTime = getTempBasalStartTime().plus(getTempBasalDuration());
return DateTime.now().isBefore(tempBasalEndTime);
}
return false;
}
public final DeliveryStatus getLastDeliveryStatus() { public final DeliveryStatus getLastDeliveryStatus() {
return getSafe(() -> podState.getLastDeliveryStatus()); return getSafe(() -> podState.getLastDeliveryStatus());
} }
@ -430,9 +462,13 @@ public abstract class PodStateManager {
podState.setReservoirLevel(statusResponse.getReservoirLevel()); podState.setReservoirLevel(statusResponse.getReservoirLevel());
podState.setTotalTicksDelivered(statusResponse.getTicksDelivered()); podState.setTotalTicksDelivered(statusResponse.getTicksDelivered());
podState.setPodProgressStatus(statusResponse.getPodProgressStatus()); podState.setPodProgressStatus(statusResponse.getPodProgressStatus());
if (!statusResponse.getDeliveryStatus().isTbrRunning()) { if (statusResponse.getDeliveryStatus().isTbrRunning()) {
if (!isTempBasalCertain() && isTempBasalRunning()) {
podState.setTempBasalCertain(true);
}
} else {
// Triggers {@link #onTbrChanged() onTbrChanged()} when appropriate // Triggers {@link #onTbrChanged() onTbrChanged()} when appropriate
setTempBasal(null, null, null, false); setTempBasal(null, null, null, true, false);
} }
podState.setLastUpdatedFromResponse(DateTime.now()); podState.setLastUpdatedFromResponse(DateTime.now());
}); });
@ -538,9 +574,11 @@ public abstract class PodStateManager {
private DateTime lastBolusStartTime; private DateTime lastBolusStartTime;
private Double lastBolusAmount; private Double lastBolusAmount;
private Duration lastBolusDuration; private Duration lastBolusDuration;
private Boolean lastBolusCertain;
private Double tempBasalAmount; private Double tempBasalAmount;
private DateTime tempBasalStartTime; private DateTime tempBasalStartTime;
private Duration tempBasalDuration; private Duration tempBasalDuration;
private Boolean tempBasalCertain;
private final Map<AlertSlot, AlertType> configuredAlerts = new HashMap<>(); private final Map<AlertSlot, AlertType> configuredAlerts = new HashMap<>();
private PodState(int address) { private PodState(int address) {
@ -751,6 +789,14 @@ public abstract class PodStateManager {
this.lastBolusDuration = lastBolusDuration; this.lastBolusDuration = lastBolusDuration;
} }
Boolean isLastBolusCertain() {
return lastBolusCertain;
}
void setLastBolusCertain(Boolean certain) {
this.lastBolusCertain = certain;
}
Double getTempBasalAmount() { Double getTempBasalAmount() {
return tempBasalAmount; return tempBasalAmount;
} }
@ -775,6 +821,14 @@ public abstract class PodStateManager {
this.tempBasalDuration = tempBasalDuration; this.tempBasalDuration = tempBasalDuration;
} }
Boolean isTempBasalCertain() {
return tempBasalCertain;
}
void setTempBasalCertain(Boolean certain) {
this.tempBasalCertain = certain;
}
Map<AlertSlot, AlertType> getConfiguredAlerts() { Map<AlertSlot, AlertType> getConfiguredAlerts() {
return configuredAlerts; return configuredAlerts;
} }

View file

@ -43,6 +43,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitReceive
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
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.communication.message.response.podinfo.PodInfoResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode;
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.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
@ -152,17 +153,15 @@ public class AapsOmnipodManager {
return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name())); return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name()));
} }
long time = System.currentTimeMillis();
try { try {
Disposable disposable = delegate.pairAndPrime().subscribe(res -> // Disposable disposable = delegate.pairAndPrime().subscribe(res -> //
handleSetupActionResult(podInitActionType, podInitReceiver, res, time, null)); handleSetupActionResult(podInitActionType, podInitReceiver, res, System.currentTimeMillis(), null));
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment); podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment);
addFailureToHistory(time, PodHistoryEntryType.PAIR_AND_PRIME, comment); addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.PAIR_AND_PRIME, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
} }
@ -172,8 +171,6 @@ public class AapsOmnipodManager {
return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name())); return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name()));
} }
long time = System.currentTimeMillis();
try { try {
BasalSchedule basalSchedule; BasalSchedule basalSchedule;
try { try {
@ -182,7 +179,7 @@ public class AapsOmnipodManager {
throw new CommandInitializationException("Basal profile mapping failed", ex); throw new CommandInitializationException("Basal profile mapping failed", ex);
} }
Disposable disposable = delegate.insertCannula(basalSchedule).subscribe(res -> // Disposable disposable = delegate.insertCannula(basalSchedule).subscribe(res -> //
handleSetupActionResult(podInitActionType, podInitReceiver, res, time, profile)); handleSetupActionResult(podInitActionType, podInitReceiver, res, System.currentTimeMillis(), profile));
rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED)); rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED));
@ -192,36 +189,34 @@ public class AapsOmnipodManager {
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment); podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment);
addFailureToHistory(time, PodHistoryEntryType.FILL_CANNULA_SET_BASAL_PROFILE, comment); addFailureToHistory(PodHistoryEntryType.FILL_CANNULA_SET_BASAL_PROFILE, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
} }
public PumpEnactResult getPodStatus() { public PumpEnactResult getPodStatus() {
long time = System.currentTimeMillis();
try { try {
StatusResponse statusResponse = delegate.getPodStatus(); StatusResponse statusResponse = delegate.getPodStatus();
addSuccessToHistory(time, PodHistoryEntryType.GET_POD_STATUS, statusResponse); addSuccessToHistory(PodHistoryEntryType.GET_POD_STATUS, statusResponse);
return new PumpEnactResult(injector).success(true).enacted(false); return new PumpEnactResult(injector).success(true).enacted(false);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, PodHistoryEntryType.GET_POD_STATUS, comment); addFailureToHistory(PodHistoryEntryType.GET_POD_STATUS, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
} }
public PumpEnactResult deactivatePod(PodInitReceiver podInitReceiver) { public PumpEnactResult deactivatePod(PodInitReceiver podInitReceiver) {
long time = System.currentTimeMillis();
try { try {
delegate.deactivatePod(); delegate.deactivatePod();
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
podInitReceiver.returnInitTaskStatus(PodInitActionType.DEACTIVATE_POD_WIZARD_STEP, false, comment); podInitReceiver.returnInitTaskStatus(PodInitActionType.DEACTIVATE_POD_WIZARD_STEP, false, comment);
addFailureToHistory(time, PodHistoryEntryType.DEACTIVATE_POD, comment); addFailureToHistory(PodHistoryEntryType.DEACTIVATE_POD, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
addSuccessToHistory(time, PodHistoryEntryType.DEACTIVATE_POD, null); addSuccessToHistory(PodHistoryEntryType.DEACTIVATE_POD, null);
createSuspendedFakeTbrIfNotExists(); createSuspendedFakeTbrIfNotExists();
@ -231,7 +226,6 @@ public class AapsOmnipodManager {
} }
public PumpEnactResult setBasalProfile(Profile profile) { public PumpEnactResult setBasalProfile(Profile profile) {
long time = System.currentTimeMillis();
PodHistoryEntryType historyEntryType = podStateManager.isSuspended() ? PodHistoryEntryType.RESUME_DELIVERY : PodHistoryEntryType.SET_BASAL_SCHEDULE; PodHistoryEntryType historyEntryType = podStateManager.isSuspended() ? PodHistoryEntryType.RESUME_DELIVERY : PodHistoryEntryType.SET_BASAL_SCHEDULE;
try { try {
@ -243,25 +237,24 @@ public class AapsOmnipodManager {
} }
delegate.setBasalSchedule(basalSchedule, isBasalBeepsEnabled()); delegate.setBasalSchedule(basalSchedule, isBasalBeepsEnabled());
time = System.currentTimeMillis();
if (historyEntryType == PodHistoryEntryType.RESUME_DELIVERY) { if (historyEntryType == PodHistoryEntryType.RESUME_DELIVERY) {
cancelSuspendedFakeTbrIfExists(); cancelSuspendedFakeTbrIfExists();
} }
addSuccessToHistory(time, historyEntryType, profile.getBasalValues()); addSuccessToHistory(historyEntryType, profile.getBasalValues());
} catch (CommandFailedAfterChangingDeliveryStatusException ex) { } catch (CommandFailedAfterChangingDeliveryStatusException ex) {
createSuspendedFakeTbrIfNotExists(); createSuspendedFakeTbrIfNotExists();
String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_suspended); String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_suspended);
showErrorDialog(comment, R.raw.boluserror); showNotification(comment, Notification.URGENT, R.raw.boluserror);
addFailureToHistory(time, historyEntryType, comment); addFailureToHistory(historyEntryType, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} catch (DeliveryStatusVerificationFailedException ex) { } catch (DeliveryStatusVerificationFailedException ex) {
String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_might_be_suspended); String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_might_be_suspended);
showErrorDialog(comment, R.raw.boluserror); showNotification(comment, Notification.URGENT, R.raw.boluserror);
addFailureToHistory(time, historyEntryType, comment); addFailureToHistory(historyEntryType, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, historyEntryType, comment); addFailureToHistory(historyEntryType, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
@ -302,9 +295,12 @@ public class AapsOmnipodManager {
if (OmnipodManager.CommandDeliveryStatus.UNCERTAIN_FAILURE.equals(bolusCommandResult.getCommandDeliveryStatus())) { if (OmnipodManager.CommandDeliveryStatus.UNCERTAIN_FAILURE.equals(bolusCommandResult.getCommandDeliveryStatus())) {
// For safety reasons, we treat this as a bolus that has successfully been delivered, in order to prevent insulin overdose // For safety reasons, we treat this as a bolus that has successfully been delivered, in order to prevent insulin overdose
if (detailedBolusInfo.isSMB) {
showNotification(getStringResource(R.string.omnipod_bolus_failed_uncertain_smb, detailedBolusInfo.insulin), Notification.URGENT, R.raw.boluserror);
} else {
showErrorDialog(getStringResource(R.string.omnipod_bolus_failed_uncertain), R.raw.boluserror); showErrorDialog(getStringResource(R.string.omnipod_bolus_failed_uncertain), R.raw.boluserror);
} }
}
detailedBolusInfo.date = bolusStarted.getTime(); detailedBolusInfo.date = bolusStarted.getTime();
detailedBolusInfo.source = Source.PUMP; detailedBolusInfo.source = Source.PUMP;
@ -393,47 +389,56 @@ public class AapsOmnipodManager {
public PumpEnactResult setTemporaryBasal(TempBasalPair tempBasalPair) { public PumpEnactResult setTemporaryBasal(TempBasalPair tempBasalPair) {
boolean beepsEnabled = isTbrBeepsEnabled(); boolean beepsEnabled = isTbrBeepsEnabled();
long time = System.currentTimeMillis();
try { try {
delegate.setTemporaryBasal(PumpType.Insulet_Omnipod.determineCorrectBasalSize(tempBasalPair.getInsulinRate()), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), beepsEnabled, beepsEnabled); delegate.setTemporaryBasal(PumpType.Insulet_Omnipod.determineCorrectBasalSize(tempBasalPair.getInsulinRate()), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), beepsEnabled, beepsEnabled);
time = System.currentTimeMillis();
} catch (CommandFailedAfterChangingDeliveryStatusException ex) { } catch (CommandFailedAfterChangingDeliveryStatusException ex) {
String comment = getStringResource(R.string.omnipod_cancelled_old_tbr_failed_to_set_new); String comment = getStringResource(R.string.omnipod_cancelled_old_tbr_failed_to_set_new);
addFailureToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, comment); addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
showNotification(comment, Notification.URGENT, null);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} catch (DeliveryStatusVerificationFailedException ex) { } catch (DeliveryStatusVerificationFailedException ex) {
String comment = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled); String comment;
if (ex.getExpectedStatus() == DeliveryStatus.TEMP_BASAL_RUNNING) {
// Happened after cancelling the old TBR, when attempting to set new TBR
comment = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed);
long pumpId = addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
// Assume that setting the temp basal succeeded here, because in case it didn't succeed,
// The next StatusResponse that we receive will allow us to recover from the wrong state
// as we can see that the delivery status doesn't actually show that a TBR is running
// If we would assume that the TBR didn't succeed, we couldn't properly recover upon the next StatusResponse,
// as we could only see that the Pod is running a TBR, but we don't know the rate and duration as
// the Pod doesn't provide this information
addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair);
} else {
// Happened when attempting to cancel the old TBR
comment = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled);
addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
}
showNotification(comment, Notification.URGENT, R.raw.boluserror); showNotification(comment, Notification.URGENT, R.raw.boluserror);
addFailureToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, comment); addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
long pumpId = addSuccessToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, tempBasalPair); long pumpId = addSuccessToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, tempBasalPair);
TemporaryBasal tempStart = new TemporaryBasal(injector) // addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair);
.date(time) //
.duration(tempBasalPair.getDurationMinutes()) //
.absolute(tempBasalPair.getInsulinRate()) //
.pumpId(pumpId)
.source(Source.PUMP);
activePlugin.getActiveTreatments().addToHistoryTempBasal(tempStart);
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} }
public PumpEnactResult cancelTemporaryBasal() { public PumpEnactResult cancelTemporaryBasal() {
long time = System.currentTimeMillis();
try { try {
delegate.cancelTemporaryBasal(isTbrBeepsEnabled()); delegate.cancelTemporaryBasal(isTbrBeepsEnabled());
addSuccessToHistory(time, PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, null); addSuccessToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, null);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, comment); addFailureToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
@ -441,30 +446,27 @@ public class AapsOmnipodManager {
} }
public PumpEnactResult acknowledgeAlerts() { public PumpEnactResult acknowledgeAlerts() {
long time = System.currentTimeMillis();
try { try {
delegate.acknowledgeAlerts(); delegate.acknowledgeAlerts();
addSuccessToHistory(time, PodHistoryEntryType.ACKNOWLEDGE_ALERTS, null); addSuccessToHistory(PodHistoryEntryType.ACKNOWLEDGE_ALERTS, null);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, PodHistoryEntryType.ACKNOWLEDGE_ALERTS, comment); addFailureToHistory(PodHistoryEntryType.ACKNOWLEDGE_ALERTS, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} }
public PumpEnactResult suspendDelivery() { public PumpEnactResult suspendDelivery() {
long time = System.currentTimeMillis();
try { try {
delegate.suspendDelivery(isBasalBeepsEnabled()); delegate.suspendDelivery(isBasalBeepsEnabled());
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, PodHistoryEntryType.SUSPEND_DELIVERY, comment); addFailureToHistory(PodHistoryEntryType.SUSPEND_DELIVERY, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
addSuccessToHistory(time, PodHistoryEntryType.SUSPEND_DELIVERY, null); addSuccessToHistory(PodHistoryEntryType.SUSPEND_DELIVERY, null);
createSuspendedFakeTbrIfNotExists(); createSuspendedFakeTbrIfNotExists();
@ -473,25 +475,23 @@ public class AapsOmnipodManager {
// Updates the pods current time based on the device timezone and the pod's time zone // Updates the pods current time based on the device timezone and the pod's time zone
public PumpEnactResult setTime() { public PumpEnactResult setTime() {
long time = System.currentTimeMillis();
try { try {
delegate.setTime(isBasalBeepsEnabled()); delegate.setTime(isBasalBeepsEnabled());
time = System.currentTimeMillis(); addSuccessToHistory(PodHistoryEntryType.SET_TIME, null);
addSuccessToHistory(time, PodHistoryEntryType.SET_TIME, null);
} catch (CommandFailedAfterChangingDeliveryStatusException ex) { } catch (CommandFailedAfterChangingDeliveryStatusException ex) {
createSuspendedFakeTbrIfNotExists(); createSuspendedFakeTbrIfNotExists();
String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_suspended); String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_suspended);
showErrorDialog(comment, R.raw.boluserror); showNotification(comment, Notification.URGENT, R.raw.boluserror);
addFailureToHistory(time, PodHistoryEntryType.SET_TIME, comment); addFailureToHistory(PodHistoryEntryType.SET_TIME, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} catch (DeliveryStatusVerificationFailedException ex) { } catch (DeliveryStatusVerificationFailedException ex) {
String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_might_be_suspended); String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_might_be_suspended);
showErrorDialog(comment, R.raw.boluserror); showNotification(comment, Notification.URGENT, R.raw.boluserror);
addFailureToHistory(time, PodHistoryEntryType.SET_TIME, comment); addFailureToHistory(PodHistoryEntryType.SET_TIME, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
addFailureToHistory(time, PodHistoryEntryType.SET_TIME, comment); addFailureToHistory(PodHistoryEntryType.SET_TIME, comment);
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
@ -587,13 +587,12 @@ public class AapsOmnipodManager {
} }
public void reportCancelledTbr() { public void reportCancelledTbr() {
long time = System.currentTimeMillis();
aapsLogger.debug(LTag.PUMP, "Reporting cancelled TBR to AAPS"); aapsLogger.debug(LTag.PUMP, "Reporting cancelled TBR to AAPS");
long pumpId = addSuccessToHistory(time, PodHistoryEntryType.CANCEL_TEMPORARY_BASAL_BY_DRIVER, null); long pumpId = addSuccessToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL_BY_DRIVER, null);
TemporaryBasal temporaryBasal = new TemporaryBasal(injector) // TemporaryBasal temporaryBasal = new TemporaryBasal(injector) //
.date(time) // .date(System.currentTimeMillis()) //
.duration(0) // .duration(0) //
.source(Source.PUMP) // .source(Source.PUMP) //
.pumpId(pumpId); .pumpId(pumpId);
@ -601,10 +600,29 @@ public class AapsOmnipodManager {
activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal); activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal);
} }
private void addTempBasalTreatment(long time, long pumpId, TempBasalPair tempBasalPair) {
TemporaryBasal tempStart = new TemporaryBasal(injector) //
.date(time) //
.duration(tempBasalPair.getDurationMinutes()) //
.absolute(tempBasalPair.getInsulinRate()) //
.pumpId(pumpId)
.source(Source.PUMP);
activePlugin.getActiveTreatments().addToHistoryTempBasal(tempStart);
}
private long addSuccessToHistory(PodHistoryEntryType entryType, Object data) {
return addSuccessToHistory(System.currentTimeMillis(), entryType, data);
}
private long addSuccessToHistory(long requestTime, PodHistoryEntryType entryType, Object data) { private long addSuccessToHistory(long requestTime, PodHistoryEntryType entryType, Object data) {
return addToHistory(requestTime, entryType, data, true); return addToHistory(requestTime, entryType, data, true);
} }
private long addFailureToHistory(PodHistoryEntryType entryType, Object data) {
return addFailureToHistory(System.currentTimeMillis(), entryType, data);
}
private long addFailureToHistory(long requestTime, PodHistoryEntryType entryType, Object data) { private long addFailureToHistory(long requestTime, PodHistoryEntryType entryType, Object data) {
return addToHistory(requestTime, entryType, data, false); return addToHistory(requestTime, entryType, data, false);
} }

View file

@ -205,6 +205,8 @@ class OmnipodFragment : DaggerFragment() {
private fun updateOmnipodStatus() { private fun updateOmnipodStatus() {
updateLastConnection() updateLastConnection()
updateLastBolus()
updateTempBasal()
updatePodStatus() updatePodStatus()
val errors = ArrayList<String>(); val errors = ArrayList<String>();
@ -228,8 +230,6 @@ class OmnipodFragment : DaggerFragment() {
omnipod_base_basal_rate.text = PLACEHOLDER omnipod_base_basal_rate.text = PLACEHOLDER
omnipod_total_delivered.text = PLACEHOLDER omnipod_total_delivered.text = PLACEHOLDER
omnipod_reservoir.text = PLACEHOLDER omnipod_reservoir.text = PLACEHOLDER
omnipod_temp_basal.text = PLACEHOLDER
omnipod_last_bolus.text = PLACEHOLDER
omnipod_pod_active_alerts.text = PLACEHOLDER omnipod_pod_active_alerts.text = PLACEHOLDER
} else { } else {
omnipod_pod_address.text = podStateManager.address.toString() omnipod_pod_address.text = podStateManager.address.toString()
@ -248,13 +248,6 @@ class OmnipodFragment : DaggerFragment() {
errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name)) errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name))
} }
// last bolus
omnipod_last_bolus.text = if (podStateManager.lastBolusStartTime != null && podStateManager.lastBolusAmount != null) {
resourceHelper.gs(R.string.omnipod_last_bolus, omnipodPumpPlugin.model().determineCorrectBolusSize(podStateManager.lastBolusAmount), resourceHelper.gs(R.string.insulin_unit_shortname), readableDuration(podStateManager.lastBolusStartTime))
} else {
PLACEHOLDER
}
val now = DateTime.now() val now = DateTime.now()
// base basal rate // base basal rate
@ -264,22 +257,6 @@ class OmnipodFragment : DaggerFragment() {
PLACEHOLDER PLACEHOLDER
} }
// Temp basal
val lastTempBasalStartTime = podStateManager.tempBasalStartTime;
val lastTempBasalAmount = podStateManager.tempBasalAmount
val lastTempBasalDuration = podStateManager.tempBasalDuration;
if (lastTempBasalStartTime != null && lastTempBasalAmount != null && lastTempBasalDuration != null) {
val endTime = lastTempBasalStartTime.plus(lastTempBasalDuration);
val minutesRunning = Duration(lastTempBasalStartTime, now).standardMinutes
omnipod_temp_basal.text = if (endTime.isAfter(now)) {
resourceHelper.gs(R.string.omnipod_temp_basal, lastTempBasalAmount, dateUtil.timeString(lastTempBasalStartTime.millis), minutesRunning, lastTempBasalDuration.standardMinutes)
} else {
PLACEHOLDER
}
} else {
omnipod_temp_basal.text = PLACEHOLDER
}
// total delivered // total delivered
omnipod_total_delivered.text = if (podStateManager.isPodActivationCompleted && podStateManager.totalInsulinDelivered != null) { omnipod_total_delivered.text = if (podStateManager.isPodActivationCompleted && podStateManager.totalInsulinDelivered != null) {
resourceHelper.gs(R.string.omnipod_total_delivered, podStateManager.totalInsulinDelivered - OmnipodConstants.POD_SETUP_UNITS); resourceHelper.gs(R.string.omnipod_total_delivered, podStateManager.totalInsulinDelivered - OmnipodConstants.POD_SETUP_UNITS);
@ -371,6 +348,55 @@ class OmnipodFragment : DaggerFragment() {
omnipod_pod_status.setTextColor(podStatusColor) omnipod_pod_status.setTextColor(podStatusColor)
} }
private fun updateLastBolus() {
if (podStateManager.isPodActivationCompleted && podStateManager.hasLastBolus()) {
var text = resourceHelper.gs(R.string.omnipod_last_bolus, omnipodPumpPlugin.model().determineCorrectBolusSize(podStateManager.lastBolusAmount), resourceHelper.gs(R.string.insulin_unit_shortname), readableDuration(podStateManager.lastBolusStartTime))
val textColor: Int
if (podStateManager.isLastBolusCertain) {
textColor = Color.WHITE
} else {
textColor = Color.RED
text += " (" + resourceHelper.gs(R.string.omnipod_uncertain) + ")"
}
omnipod_last_bolus.text = text;
omnipod_last_bolus.setTextColor(textColor)
} else {
omnipod_last_bolus.text = PLACEHOLDER
omnipod_last_bolus.setTextColor(Color.WHITE)
}
}
private fun updateTempBasal() {
if (podStateManager.isPodActivationCompleted && podStateManager.isTempBasalRunning) {
val now = DateTime.now()
val startTime = podStateManager.tempBasalStartTime;
val amount = podStateManager.tempBasalAmount
val duration = podStateManager.tempBasalDuration;
val minutesRunning = Duration(startTime, now).standardMinutes
var text: String
val textColor: Int
text = resourceHelper.gs(R.string.omnipod_temp_basal, amount, dateUtil.timeString(startTime.millis), minutesRunning, duration.standardMinutes)
if (podStateManager.isTempBasalCertain) {
textColor = Color.WHITE
} else {
textColor = Color.RED
text += " (" + resourceHelper.gs(R.string.omnipod_uncertain) + ")"
}
omnipod_temp_basal.text = text;
omnipod_temp_basal.setTextColor(textColor)
} else {
omnipod_temp_basal.text = PLACEHOLDER
omnipod_temp_basal.setTextColor(Color.WHITE)
}
}
private fun updateQueueStatus() { private fun updateQueueStatus() {
if (isQueueEmpty()) { if (isQueueEmpty()) {
omnipod_queue.visibility = View.GONE omnipod_queue.visibility = View.GONE

View file

@ -133,12 +133,14 @@
<string name="omnipod_alert_shutdown_imminent">Shutdown is imminent</string> <string name="omnipod_alert_shutdown_imminent">Shutdown is imminent</string>
<string name="omnipod_alert_low_reservoir">Low reservoir</string> <string name="omnipod_alert_low_reservoir">Low reservoir</string>
<string name="omnipod_alert_unknown_alert">Unknown alert</string> <string name="omnipod_alert_unknown_alert">Unknown alert</string>
<string name="omnipod_error_set_basal_failed_delivery_might_be_suspended">Setting basal profile might have failed. Delivery might be suspended! Please refresh Pod status and resume delivery from the Omnipod tab if needed.</string> <string name="omnipod_error_set_basal_failed_delivery_might_be_suspended">Setting basal profile might have failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
<string name="omnipod_error_set_basal_failed_delivery_suspended">Setting basal profile failed. Delivery is suspended! Please resume delivery from the Omnipod tab.</string> <string name="omnipod_error_set_basal_failed_delivery_suspended">Setting basal profile failed. Delivery is suspended! Please manually resume delivery from the Omnipod tab.</string>
<string name="omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled">Setting temp basal might have failed. If a temp basal was already running, it might have been cancelled without AndroidAPS being aware!</string> <string name="omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled">Setting temp basal failed. If a temp basal was previously running, it might have been cancelled. Please manually refresh the Pod status from the Omnipod tab.</string>
<string name="omnipod_error_set_time_failed_delivery_might_be_suspended">Setting time might have failed. Delivery might be suspended! Please refresh Pod status and resume delivery from the Omnipod tab if needed.</string> <string name="omnipod_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed">Setting temp might have basal failed. If a temp basal was previously running, it has been cancelled. Please manually refresh the Pod status from the Omnipod tab.</string>
<string name="omnipod_error_set_time_failed_delivery_suspended">Setting time failed. Delivery is suspended! Please resume delivery from the Omnipod tab.</string> <string name="omnipod_error_set_time_failed_delivery_might_be_suspended">Setting time might have failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
<string name="omnipod_bolus_failed_uncertain">Unable to verify whether the bolus succeeded. Please verify that your Pod is bolusing or cancel the bolus.</string> <string name="omnipod_error_set_time_failed_delivery_suspended">Setting time failed. Delivery is suspended! Please manually resume delivery from the Omnipod tab.</string>
<string name="omnipod_bolus_failed_uncertain">Unable to verify whether the bolus succeeded. Please manually verify that your Pod is bolusing by listening to clicks. <b>If you are sure that the bolus didn\'t succeed, you should manually delete the bolus entry from Treatments, even if you click \'Cancel bolus\' now!</b></string>
<string name="omnipod_bolus_failed_uncertain_smb">Unable to verify whether SMB bolus (%1$.2f U) succeeded. <b>If you are sure that the Bolus didn\'t succeed, you should manually delete the SMB entry from Treatments.</b></string>
<string name="omnipod_rl_stats">RL stats</string> <string name="omnipod_rl_stats">RL stats</string>
<string name="omnipod_read_pulse_log_short">Pulse log</string> <string name="omnipod_read_pulse_log_short">Pulse log</string>
<string name="omnipod_pod_lot">LOT</string> <string name="omnipod_pod_lot">LOT</string>
@ -165,6 +167,7 @@
<string name="omnipod_cancelled_old_tbr_failed_to_set_new">Cancelled the old temporary basal, but failed to set new temporary basal</string> <string name="omnipod_cancelled_old_tbr_failed_to_set_new">Cancelled the old temporary basal, but failed to set new temporary basal</string>
<string name="omnipod_cmd_set_fake_suspended_tbr">Set fake temporary basal because the Pod is suspended</string> <string name="omnipod_cmd_set_fake_suspended_tbr">Set fake temporary basal because the Pod is suspended</string>
<string name="omnipod_cmd_cancel_fake_suspended_tbr">Cancel fake temporary basal that was created because the Pod was suspended</string> <string name="omnipod_cmd_cancel_fake_suspended_tbr">Cancel fake temporary basal that was created because the Pod was suspended</string>
<string name="omnipod_uncertain">uncertain</string>
<plurals name="omnipod_minutes"> <plurals name="omnipod_minutes">
<item quantity="one">%1$d minute</item> <item quantity="one">%1$d minute</item>