Take Basal into account when calculating bolus duration
This commit is contained in:
parent
5f28740068
commit
e891f26be0
|
@ -21,10 +21,8 @@ public class OmnipodConstants {
|
||||||
public static final Duration AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION = Duration.millis(1500);
|
public static final Duration AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION = Duration.millis(1500);
|
||||||
|
|
||||||
public static final Duration SERVICE_DURATION = Duration.standardHours(80);
|
public static final Duration SERVICE_DURATION = Duration.standardHours(80);
|
||||||
public static final Duration EXPIRATION_ADVISORY_WINDOW = Duration.standardHours(9);
|
|
||||||
public static final Duration END_OF_SERVICE_IMMINENT_WINDOW = Duration.standardHours(1);
|
public static final Duration END_OF_SERVICE_IMMINENT_WINDOW = Duration.standardHours(1);
|
||||||
public static final Duration NOMINAL_POD_LIFE = Duration.standardHours(72);
|
public static final Duration NOMINAL_POD_LIFE = Duration.standardHours(72);
|
||||||
public static final double LOW_RESERVOIR_ALERT = 20.0;
|
|
||||||
|
|
||||||
public static final double POD_PRIME_BOLUS_UNITS = 2.6;
|
public static final double POD_PRIME_BOLUS_UNITS = 2.6;
|
||||||
public static final double POD_CANNULA_INSERTION_BOLUS_UNITS = 0.5;
|
public static final double POD_CANNULA_INSERTION_BOLUS_UNITS = 0.5;
|
||||||
|
|
|
@ -126,9 +126,9 @@ public class OmnipodManager {
|
||||||
logCommandExecutionFinished("pairAndPrime");
|
logCommandExecutionFinished("pairAndPrime");
|
||||||
}
|
}
|
||||||
|
|
||||||
long delayInSeconds = calculateBolusDuration(OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getStandardSeconds();
|
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(delayInSeconds, TimeUnit.SECONDS) //
|
return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) //
|
||||||
.map(o -> verifySetupAction(PodProgressStatus.PRIMING_COMPLETED)) //
|
.map(o -> verifySetupAction(PodProgressStatus.PRIMING_COMPLETED)) //
|
||||||
.observeOn(Schedulers.io());
|
.observeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
@ -154,9 +154,9 @@ public class OmnipodManager {
|
||||||
logCommandExecutionFinished("insertCannula");
|
logCommandExecutionFinished("insertCannula");
|
||||||
}
|
}
|
||||||
|
|
||||||
long delayInSeconds = calculateBolusDuration(OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getStandardSeconds();
|
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(delayInSeconds, TimeUnit.SECONDS) //
|
return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) //
|
||||||
.map(o -> verifySetupAction(PodProgressStatus.ABOVE_FIFTY_UNITS)) //
|
.map(o -> verifySetupAction(PodProgressStatus.ABOVE_FIFTY_UNITS)) //
|
||||||
.observeOn(Schedulers.io());
|
.observeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ public class OmnipodManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime estimatedBolusStartDate = DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
|
DateTime estimatedBolusStartDate = DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
|
||||||
Duration estimatedBolusDuration = calculateBolusDuration(units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE);
|
Duration estimatedBolusDuration = calculateEstimatedBolusDuration(estimatedBolusStartDate, units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE);
|
||||||
Duration estimatedRemainingBolusDuration = estimatedBolusDuration.minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
|
Duration estimatedRemainingBolusDuration = estimatedBolusDuration.minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
|
||||||
|
|
||||||
podStateManager.setLastBolus(estimatedBolusStartDate, units, estimatedBolusDuration, commandDeliveryStatus == CommandDeliveryStatus.SUCCESS);
|
podStateManager.setLastBolus(estimatedBolusStartDate, units, estimatedBolusDuration, commandDeliveryStatus == CommandDeliveryStatus.SUCCESS);
|
||||||
|
@ -376,7 +376,7 @@ public class OmnipodManager {
|
||||||
|
|
||||||
if (progressIndicationConsumer != null) {
|
if (progressIndicationConsumer != null) {
|
||||||
|
|
||||||
int numberOfProgressReports = Math.max(20, Math.min(100, (int) Math.ceil(units) * 10));
|
long numberOfProgressReports = Math.max(10, Math.min(100, estimatedRemainingBolusDuration.getStandardSeconds()));
|
||||||
long progressReportInterval = estimatedRemainingBolusDuration.getMillis() / numberOfProgressReports;
|
long progressReportInterval = estimatedRemainingBolusDuration.getMillis() / numberOfProgressReports;
|
||||||
|
|
||||||
disposables.add(Flowable.intervalRange(0, numberOfProgressReports + 1, 0, progressReportInterval, TimeUnit.MILLISECONDS) //
|
disposables.add(Flowable.intervalRange(0, numberOfProgressReports + 1, 0, progressReportInterval, TimeUnit.MILLISECONDS) //
|
||||||
|
@ -664,14 +664,27 @@ public class OmnipodManager {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Command execution finished for action: " + action);
|
aapsLogger.debug(LTag.PUMPCOMM, "Command execution finished for action: " + action);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Duration calculateBolusDuration(double units, double deliveryRate) {
|
private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) {
|
||||||
// TODO take current (temp) basal into account
|
if (!podStateManager.isPodActivationCompleted()) {
|
||||||
// Be aware that the Pod possibly doesn't have a Basal Schedule yet
|
// No basal or temp basal is active yet
|
||||||
return Duration.standardSeconds((long) Math.ceil(units / deliveryRate));
|
return Duration.standardSeconds((long) Math.ceil(units / deliveryRateInUnitsPerSecond));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Duration calculateBolusDuration(double units) {
|
double pulseIntervalInSeconds = OmnipodConstants.POD_PULSE_SIZE / deliveryRateInUnitsPerSecond;
|
||||||
return calculateBolusDuration(units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE);
|
long numberOfPulses = Math.round(units / OmnipodConstants.POD_PULSE_SIZE);
|
||||||
|
double totalEstimatedDurationInSeconds = 0D;
|
||||||
|
|
||||||
|
for (int i = 0; numberOfPulses > i; i++) {
|
||||||
|
DateTime estimatedTimeAtPulse = startTime.plusMillis((int) (totalEstimatedDurationInSeconds * 1000));
|
||||||
|
double effectiveBasalRateAtPulse = podStateManager.getEffectiveBasalRateAt(estimatedTimeAtPulse);
|
||||||
|
double effectivePulsesPerHourAtPulse = effectiveBasalRateAtPulse / OmnipodConstants.POD_PULSE_SIZE;
|
||||||
|
double effectiveBasalPulsesPerSecondAtPulse = effectivePulsesPerHourAtPulse / 3600;
|
||||||
|
double effectiveBasalPulsesPerBolusPulse = pulseIntervalInSeconds * effectiveBasalPulsesPerSecondAtPulse;
|
||||||
|
|
||||||
|
totalEstimatedDurationInSeconds += pulseIntervalInSeconds * (1 + effectiveBasalPulsesPerBolusPulse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Duration.millis(Math.round(totalEstimatedDurationInSeconds * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCertainFailure(Exception ex) {
|
public static boolean isCertainFailure(Exception ex) {
|
||||||
|
|
|
@ -427,16 +427,50 @@ public abstract class PodStateManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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)
|
* @return true when a Temp Basal is stored in the Pod State and this temp basal is currently running (based on start time and duration)
|
||||||
*/
|
*/
|
||||||
public final boolean isTempBasalRunning() {
|
public final boolean isTempBasalRunning() {
|
||||||
|
return isTempBasalRunningAt(DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true when a Temp Basal is stored in the Pod State and this temp basal is running at the given time (based on start time and duration)
|
||||||
|
*/
|
||||||
|
public final boolean isTempBasalRunningAt(DateTime time) {
|
||||||
if (hasTempBasal()) {
|
if (hasTempBasal()) {
|
||||||
DateTime tempBasalEndTime = getTempBasalStartTime().plus(getTempBasalDuration());
|
DateTime tempBasalStartTime = getTempBasalStartTime();
|
||||||
return DateTime.now().isBefore(tempBasalEndTime);
|
DateTime tempBasalEndTime = tempBasalStartTime.plus(getTempBasalDuration());
|
||||||
|
return (time.isAfter(tempBasalStartTime) || time.isEqual(tempBasalStartTime)) && time.isBefore(tempBasalEndTime);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current effective basal rate (taking Pod suspension, TBR, and basal profile into account)
|
||||||
|
*/
|
||||||
|
public final double getEffectiveBasalRate() {
|
||||||
|
if (isSuspended()) {
|
||||||
|
return 0d;
|
||||||
|
}
|
||||||
|
return getEffectiveBasalRateAt(DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the effective basal rate at the given time (taking TBR, and basal profile into account)
|
||||||
|
* Suspension is not taken into account as we don't keep historic data of that
|
||||||
|
*/
|
||||||
|
public final double getEffectiveBasalRateAt(DateTime time) {
|
||||||
|
BasalSchedule basalSchedule = getSafe(() -> podState.getBasalSchedule());
|
||||||
|
if (basalSchedule == null) {
|
||||||
|
return 0d;
|
||||||
|
}
|
||||||
|
if (isTempBasalRunningAt(time)) {
|
||||||
|
return getTempBasalAmount();
|
||||||
|
}
|
||||||
|
Duration offset = new Duration(time.withTimeAtStartOfDay(), time);
|
||||||
|
return basalSchedule.rateAt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
public final DeliveryStatus getLastDeliveryStatus() {
|
public final DeliveryStatus getLastDeliveryStatus() {
|
||||||
return getSafe(() -> podState.getLastDeliveryStatus());
|
return getSafe(() -> podState.getLastDeliveryStatus());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue