Initial work on basing boluses on pump history.

This commit is contained in:
Johannes Mockenhaupt 2018-01-28 15:22:41 +01:00
parent 3d1f8c0893
commit b3a60eb5ab
No known key found for this signature in database
GPG key ID: 9E1EA6AF7BBBB0D1
5 changed files with 194 additions and 154 deletions

View file

@ -713,24 +713,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} }
@Nullable
public Treatment getTreatmentByDate(long mills) {
try {
Dao<Treatment, Long> daoTreatments = getDaoTreatments();
List<Treatment> treatments;
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
Where where = queryBuilder.where();
where.eq("date", mills);
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
treatments = daoTreatments.query(preparedQuery);
// date is unique
return treatments.isEmpty() ? null : treatments.get(0);
} catch (SQLException e) {
log.error("Unhandled exception", e);
return null;
}
}
public List<Treatment> getTreatmentDataFromTime(long mills, boolean ascending) { public List<Treatment> getTreatmentDataFromTime(long mills, boolean ascending) {
try { try {
Dao<Treatment, Long> daoTreatments = getDaoTreatments(); Dao<Treatment, Long> daoTreatments = getDaoTreatments();
@ -1086,23 +1068,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
scheduleTemporaryBasalChange(); scheduleTemporaryBasalChange();
} }
@Nullable
public TemporaryBasal getTemporaryBasalsDataByDate(long startTime) {
try {
List<TemporaryBasal> tempbasals;
QueryBuilder<TemporaryBasal, Long> queryBuilder = getDaoTemporaryBasal().queryBuilder();
Where where = queryBuilder.where();
where.eq("date", startTime);
PreparedQuery<TemporaryBasal> preparedQuery = queryBuilder.prepare();
tempbasals = getDaoTemporaryBasal().query(preparedQuery);
// date is unique
return tempbasals.isEmpty() ? null : tempbasals.get(0);
} catch (SQLException e) {
log.error("Unhandled exception", e);
}
return null;
}
public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long mills, boolean ascending) { public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long mills, boolean ascending) {
try { try {
List<TemporaryBasal> tempbasals; List<TemporaryBasal> tempbasals;

View file

@ -85,7 +85,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
case R.id.combo_full_history_button: case R.id.combo_full_history_button:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.combo_warning); builder.setTitle(R.string.combo_warning);
builder.setMessage(R.string.combo_read_full_history_warning); builder.setMessage(R.string.combo_read_full_history_info);
builder.show(); builder.show();
break; break;
} }
@ -101,13 +101,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
new Thread(() -> ComboPlugin.getPlugin().readTddData()).start(); new Thread(() -> ComboPlugin.getPlugin().readTddData()).start();
return true; return true;
case R.id.combo_full_history_button: case R.id.combo_full_history_button:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); new Thread(() -> ComboPlugin.getPlugin().readAllPumpData()).start();
builder.setTitle(R.string.combo_warning);
builder.setMessage(R.string.combo_read_full_history_confirmation);
builder.setPositiveButton(R.string.ok, (dialog, which) ->
new Thread(() -> ComboPlugin.getPlugin().readAllPumpData()).start());
builder.setNegativeButton(MainApp.gs(R.string.cancel), null);
builder.show();
return true; return true;
} }
return false; return false;

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.PumpCombo;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent; import com.crashlytics.android.answers.CustomEvent;
@ -10,6 +11,7 @@ import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -101,8 +103,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
private volatile boolean bolusInProgress; private volatile boolean bolusInProgress;
private volatile boolean cancelBolus; private volatile boolean cancelBolus;
private Bolus lastRequestedBolus; private Bolus lastRequestedBolus;
private long pumpHistoryLastChecked; // private long pumpHistoryLastChecked;
private volatile long timestampOfLastKnownBolusRecord;
/** this is set whenever a connection to the pump is made and indicates if new history
records on the pump have been found */
private volatile boolean pumpHistoryChanged = false;
public static ComboPlugin getPlugin() { public static ComboPlugin getPlugin() {
if (plugin == null) if (plugin == null)
@ -347,6 +355,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
initializePump(); initializePump();
} else { } else {
runCommand(MainApp.gs(R.string.combo_pump_action_refreshing), 1, ruffyScripter::readPumpState); runCommand(MainApp.gs(R.string.combo_pump_action_refreshing), 1, ruffyScripter::readPumpState);
// note that since the history is checked upon every connect, the above already updated
// the DB with any changed history records
} }
} }
@ -368,6 +378,13 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return; return;
} }
// note that since the history is checked upon every connect, the above already updated
// the DB with any changed history records
if (pumpHistoryChanged) {
log.debug("Pump history has changed and was imported");
pumpHistoryChanged = false;
}
if (stateResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) { if (stateResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) {
Notification n = new Notification(Notification.COMBO_PUMP_ALARM, Notification n = new Notification(Notification.COMBO_PUMP_ALARM,
MainApp.gs(R.string.combo_force_disabled_notification), MainApp.gs(R.string.combo_force_disabled_notification),
@ -384,6 +401,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
pump.basalProfile = readBasalResult.basalProfile; pump.basalProfile = readBasalResult.basalProfile;
validBasalRateProfileSelectedOnPump = true; validBasalRateProfileSelectedOnPump = true;
pump.initialized = true; pump.initialized = true;
MainApp.bus().post(new EventInitializationChanged()); MainApp.bus().post(new EventInitializationChanged());
@ -474,15 +492,31 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return new PumpEnactResult().success(false).enacted(false) return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.bolus_frequency_exceeded)); .comment(MainApp.gs(R.string.bolus_frequency_exceeded));
} }
// TODO only check this after a bolus was successfully applied? NO, because in error condition
// we can't say with certainty if a bolus was delivered (we find out when refreshing history next)
// so, be on the annoying but safe side
lastRequestedBolus = new Bolus(System.currentTimeMillis(), detailedBolusInfo.insulin, true); lastRequestedBolus = new Bolus(System.currentTimeMillis(), detailedBolusInfo.insulin, true);
CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState); CommandResult stateResult = runCommand(null, 2, ruffyScripter::readReservoirLevelAndLastBolus);
long pumpTimeWhenBolusWasRequested = stateResult .state.pumpTime; long pumpTimeWhenBolusWasRequested = stateResult .state.pumpTime;
if (!stateResult.success || pumpTimeWhenBolusWasRequested == 0) { if (!stateResult.success || pumpTimeWhenBolusWasRequested == 0) {
return new PumpEnactResult().success(false).enacted(false) return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.combo_error_no_bolus_delivered)); .comment(MainApp.gs(R.string.combo_error_no_bolus_delivered));
} }
if (stateResult.reservoirLevel - 0.5 < detailedBolusInfo.insulin) {
return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.combo_reservoir_level_insufficient_for_bolus));
}
// the commands above ensured a connection was made, which updated this field
if (pumpHistoryChanged) {
return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.combo_bolus_rejected_due_to_pump_history_change));
}
Bolus previousBolus = stateResult.lastBolus != null ? stateResult.lastBolus : new Bolus(0, 0, false);
try { try {
pump.activity = MainApp.gs(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin); pump.activity = MainApp.gs(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin);
MainApp.bus().post(new EventComboPumpUpdateGUI()); MainApp.bus().post(new EventComboPumpUpdateGUI());
@ -499,21 +533,54 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
() -> ruffyScripter.deliverBolus(detailedBolusInfo.insulin, progressReporter)); () -> ruffyScripter.deliverBolus(detailedBolusInfo.insulin, progressReporter));
bolusInProgress = false; bolusInProgress = false;
if (bolusCmdResult.success) { // Note that the result of the issues the bolus command is not checked. If there was
if (bolusCmdResult.delivered > 0) { // a connection problem, ruffyscripter tried to recover and we can just check the
detailedBolusInfo.insulin = bolusCmdResult.delivered; // history below
detailedBolusInfo.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); // TODO test and check error messages, they're not as fine-grained as they used to be.
// maybe they shouldn't even be, if there was an error, the user should check anyways
CommandResult postBolusStateResult = runCommand(null, 1, ruffyScripter::readReservoirLevelAndLastBolus);
if (!postBolusStateResult.success) {
return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.combo_error_bolus_verification_failed));
} }
Bolus lastBolus = postBolusStateResult.lastBolus;
if (lastBolus == null || lastBolus.equals(previousBolus)) {
return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.combo_error_bolus_verification_failed));
}
List<Bolus> bolusList = new ArrayList<>(1);
bolusList.add(lastBolus);
boolean pumpRecordedAdded = updateDbFromPumpHistory(new PumpHistory().bolusHistory(bolusList));
if (!pumpRecordedAdded) {
return new PumpEnactResult().success(false).enacted(false)
.comment(MainApp.gs(R.string.combo_error_bolus_verification_failed));
}
return new PumpEnactResult() return new PumpEnactResult()
.success(true) .success(true)
.enacted(bolusCmdResult.delivered > 0) .enacted(bolusCmdResult.delivered > 0)
.bolusDelivered(bolusCmdResult.delivered) .bolusDelivered(bolusCmdResult.delivered)
.carbsDelivered(detailedBolusInfo.carbs); .carbsDelivered(detailedBolusInfo.carbs);
} else {
progressReporter.report(BolusProgressReporter.State.RECOVERING, 0, 0); // if (bolusCmdResult.success) {
return recoverFromErrorDuringBolusDelivery(detailedBolusInfo, pumpTimeWhenBolusWasRequested); // if (bolusCmdResult.delivered > 0) {
} // detailedBolusInfo.insulin = bolusCmdResult.delivered;
// detailedBolusInfo.source = Source.USER;
// MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
// }
// return new PumpEnactResult()
// .success(true)
// .enacted(bolusCmdResult.delivered > 0)
// .bolusDelivered(bolusCmdResult.delivered)
// .carbsDelivered(detailedBolusInfo.carbs);
// } else {
// progressReporter.report(BolusProgressReporter.State.RECOVERING, 0, 0);
// return recoverFromErrorDuringBolusDelivery(detailedBolusInfo, pumpTimeWhenBolusWasRequested);
// }
} finally { } finally {
pump.activity = null; pump.activity = null;
MainApp.bus().post(new EventComboPumpUpdateGUI()); MainApp.bus().post(new EventComboPumpUpdateGUI());
@ -522,7 +589,6 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
} }
/** /**
* If there was an error during BolusCommand the scripter reconnects and cleans up. The pump * If there was an error during BolusCommand the scripter reconnects and cleans up. The pump
* refuses connections while a bolus delivery is still in progress (once bolus delivery started * refuses connections while a bolus delivery is still in progress (once bolus delivery started
@ -589,13 +655,16 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
cancelBolus = true; cancelBolus = true;
} }
// Note: AAPS calls this solely to enact OpenAPS suggestions /** Note: AAPS calls this solely to enact OpenAPS suggestions
*
* @param force the force parameter isn't used currently since we always set the tbr -
* there might be room for optimization to first test the currently running tbr
* and only change it if it differs (as the DanaR plugin does). This approach
* might have other issues though (what happens if the tbr which wasn't re-set to
* the new value (and thus still has the old duration of e.g. 1 min) expires?)
*/
@Override @Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force) { public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force) {
// the force parameter isn't used currently since we always set the tbr - there might be room for optimization to
// first test the currently running tbr and only change it if it differs (as the DanaR plugin does).
// This approach might have other issues though (what happens if the tbr which wasn't re-set to the new value
// (and thus still has the old duration of e.g. 1 min) expires?)
log.debug("setTempBasalAbsolute called with a rate of " + absoluteRate + " for " + durationInMinutes + " min."); log.debug("setTempBasalAbsolute called with a rate of " + absoluteRate + " for " + durationInMinutes + " min.");
int unroundedPercentage = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue(); int unroundedPercentage = Double.valueOf(absoluteRate / getBaseBasalRate() * 100).intValue();
int roundedPercentage = (int) (Math.round(absoluteRate / getBaseBasalRate() * 10) * 10); int roundedPercentage = (int) (Math.round(absoluteRate / getBaseBasalRate() * 10) * 10);
@ -620,6 +689,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
private PumpEnactResult setTempBasalPercent(Integer percent, final Integer durationInMinutes) { private PumpEnactResult setTempBasalPercent(Integer percent, final Integer durationInMinutes) {
log.debug("setTempBasalPercent called with " + percent + "% for " + durationInMinutes + "min"); log.debug("setTempBasalPercent called with " + percent + "% for " + durationInMinutes + "min");
if (pumpHistoryChanged && percent > 110) {
return new PumpEnactResult().success(false).enacted(false)
.comment("Rejecting high temp since calculation didn't consider recently changed pump history");
}
int adjustedPercent = percent; int adjustedPercent = percent;
if (adjustedPercent > pumpDescription.maxTempPercent) { if (adjustedPercent > pumpDescription.maxTempPercent) {
@ -763,8 +837,6 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
} }
checkForUnsafeUsage(commandResult);
return commandResult; return commandResult;
} }
@ -801,8 +873,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
} }
checkForUnsafeUsage(preCheckResult);
checkAndResolveTbrMismatch(preCheckResult.state); checkAndResolveTbrMismatch(preCheckResult.state);
checkPumpTime(preCheckResult.state); checkPumpTime(preCheckResult.state);
checkHistory();
return null; return null;
} }
@ -922,7 +996,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
* Only ever called by #readAllPumpData which is triggered by the user via the combo fragment * Only ever called by #readAllPumpData which is triggered by the user via the combo fragment
* which warns the user against doing this. * which warns the user against doing this.
*/ */
private boolean readHistory(final PumpHistoryRequest request) { private boolean readHistory(@Nullable PumpHistoryRequest request) {
CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request)); CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request));
if (!historyResult.success) { if (!historyResult.success) {
return false; return false;
@ -942,38 +1016,36 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return historyResult.success; return historyResult.success;
} }
private synchronized void updateDbFromPumpHistory(@NonNull PumpHistory history) { private boolean updateDbFromPumpHistory(@NonNull PumpHistory history) {
DatabaseHelper dbHelper = MainApp.getDbHelper(); boolean updated = false;
// boluses // Bolus
for (Bolus pumpBolus : history.bolusHistory) { for (Bolus pumpBolus : history.bolusHistory) {
Treatment aapsBolus = dbHelper.getTreatmentByDate(pumpBolus.timestamp);
if (aapsBolus == null) {
log.debug("Creating bolus record from pump bolus: " + pumpBolus);
DetailedBolusInfo dbi = new DetailedBolusInfo(); DetailedBolusInfo dbi = new DetailedBolusInfo();
dbi.date = pumpBolus.timestamp; dbi.date = pumpBolus.timestamp;
dbi.pumpId = pumpBolus.timestamp; dbi.pumpId = pumpBolus.timestamp + ((int) pumpBolus.amount * 10);
dbi.source = Source.PUMP; dbi.source = Source.PUMP;
dbi.insulin = pumpBolus.amount; dbi.insulin = pumpBolus.amount;
dbi.eventType = CareportalEvent.CORRECTIONBOLUS; dbi.eventType = CareportalEvent.CORRECTIONBOLUS;
MainApp.getConfigBuilder().addToHistoryTreatment(dbi); if (MainApp.getConfigBuilder().addToHistoryTreatment(dbi)) {
updated = true;
} }
} }
// TBRs // TBRs
for (Tbr pumpTbr : history.tbrHistory) { for (Tbr pumpTbr : history.tbrHistory) {
TemporaryBasal aapsTbr = dbHelper.getTemporaryBasalsDataByDate(pumpTbr.timestamp);
if (aapsTbr == null) {
log.debug("Creating TBR from pump TBR: " + pumpTbr);
TemporaryBasal temporaryBasal = new TemporaryBasal(); TemporaryBasal temporaryBasal = new TemporaryBasal();
temporaryBasal.date = pumpTbr.timestamp; temporaryBasal.date = pumpTbr.timestamp;
temporaryBasal.pumpId = pumpTbr.timestamp; temporaryBasal.pumpId = pumpTbr.timestamp + pumpTbr.percent;
temporaryBasal.source = Source.PUMP; temporaryBasal.source = Source.PUMP;
temporaryBasal.percentRate = pumpTbr.percent; temporaryBasal.percentRate = pumpTbr.percent;
temporaryBasal.durationInMinutes = pumpTbr.duration; temporaryBasal.durationInMinutes = pumpTbr.duration;
temporaryBasal.isAbsolute = false; temporaryBasal.isAbsolute = false;
MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal); if (MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal)) {
updated = true;
} }
} }
return updated;
} }
// TODO queue // TODO queue
@ -990,37 +1062,40 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
// TODO queue // TODO queue
void readAllPumpData() { void readAllPumpData() {
long lastCheckInitiated = System.currentTimeMillis(); readHistory(new PumpHistoryRequest()
.bolusHistory(PumpHistoryRequest.FULL)
boolean readHistorySuccess = readHistory(new PumpHistoryRequest() .tbrHistory(PumpHistoryRequest.FULL)
.bolusHistory(pumpHistoryLastChecked)
.tbrHistory(pumpHistoryLastChecked)
.pumpErrorHistory(PumpHistoryRequest.FULL) .pumpErrorHistory(PumpHistoryRequest.FULL)
.tddHistory(PumpHistoryRequest.FULL)); .tddHistory(PumpHistoryRequest.FULL)
if (!readHistorySuccess) { );
return; runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile);
}
pumpHistoryLastChecked = lastCheckInitiated;
/* not displayed in the UI anymore due to pump bug
CommandResult reservoirResult = runCommand("Checking reservoir level", 2,
ruffyScripter::readReservoirLevelAndLastBolus);
if (!reservoirResult.success) {
return;
}
*/
CommandResult basalResult = runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile);
if (!basalResult.success) {
return;
}
pump.basalProfile = basalResult.basalProfile;
ruffyScripter.disconnect(); ruffyScripter.disconnect();
} }
private void checkHistory() {
long start = System.currentTimeMillis();
// long lastCheckInitiated = System.currentTimeMillis();
CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () ->
ruffyScripter.readHistory(new PumpHistoryRequest()
.bolusHistory(timestampOfLastKnownBolusRecord)
// TODO TBR history will almost always produce changes
// .tbrHistory(pumpHistoryLastChecked))
));
if (!historyResult.success) {
return;
}
pumpHistoryChanged = updateDbFromPumpHistory(historyResult.history);
if (!historyResult.history.bolusHistory.isEmpty()) {
timestampOfLastKnownBolusRecord = historyResult.history.bolusHistory.get(0).timestamp;
}
// pumpHistoryLastChecked = lastCheckInitiated;
long end = System.currentTimeMillis();
log.debug("History check took: " + ((end - start) / 1000) + "s");
}
@Override @Override
public PumpEnactResult cancelExtendedBolus() { public PumpEnactResult cancelExtendedBolus() {
return OPERATION_NOT_SUPPORTED; return OPERATION_NOT_SUPPORTED;

View file

@ -854,6 +854,7 @@
<string name="combo_notification_check_time_date">Pump clock update needed</string> <string name="combo_notification_check_time_date">Pump clock update needed</string>
<string name="combo_history">History</string> <string name="combo_history">History</string>
<string name="combo_warning">Warning</string> <string name="combo_warning">Warning</string>
<string name="combo_read_full_history_info">Long press this button to (re)read all history data and basal profile from the pump. This is generally not needed, but can be useful if the pump\'s date and time was significantly off or the basal profile was changed on the pump (which should never be done under normal circumstances).</string>
<string name="combo_read_full_history_warning">This will read the full history and state of the pump. Everything in \"My Data\" and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again.\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided.</string> <string name="combo_read_full_history_warning">This will read the full history and state of the pump. Everything in \"My Data\" and the basal rate. Boluses and TBRs will be added to Treatments if they don\'t already exist. This can cause entries to be duplicated because the pump\'s time is imprecise. Using this when normally looping with the pump is highly discouraged and reserved for special circumstances. If you still want to do this, long press this button again.\n\nWARNING: this can trigger a bug which causes the pump to reject all connection attempts and requires pressing a button on the pump to recover and should therefore be avoided.</string>
<string name="combo_read_full_history_confirmation">Are you really sure you want to read all pump data and take the consequences of this action?</string> <string name="combo_read_full_history_confirmation">Are you really sure you want to read all pump data and take the consequences of this action?</string>
<string name="combo_pump_tbr_cancelled_warrning">TBR CANCELLED warning was confirmed</string> <string name="combo_pump_tbr_cancelled_warrning">TBR CANCELLED warning was confirmed</string>
@ -865,5 +866,6 @@
<string name="extendedbolusdeliveryerror">Extended bolus delivery error</string> <string name="extendedbolusdeliveryerror">Extended bolus delivery error</string>
<string name="pump_basebasalrate">%.2f U/h</string> <string name="pump_basebasalrate">%.2f U/h</string>
<string name="combo_actvity_reading_basal_profile">Reading basal profile</string> <string name="combo_actvity_reading_basal_profile">Reading basal profile</string>
<string name="combo_bolus_rejected_due_to_pump_history_change">The pump history has changed after the bolus calculation was performed. The bolus was not delivered. Please recalculate if a bolus is still needed. If the same bolus amount is required, please wait a minute since boluses with the same amount are blocked when requested within the same minute for saftery (regardless of whether they were administered or not).</string>
</resources> </resources>

View file

@ -60,6 +60,9 @@ public class ReadHistoryCommand extends BaseCommand {
} }
} }
if (request.pumpErrorHistory == PumpHistoryRequest.SKIP
&& request.tddHistory == PumpHistoryRequest.SKIP
&& request.tbrHistory == PumpHistoryRequest.SKIP) {
// error history // error history
scripter.pressMenuKey(); scripter.pressMenuKey();
scripter.verifyMenuIsDisplayed(MenuType.ERROR_DATA); scripter.verifyMenuIsDisplayed(MenuType.ERROR_DATA);
@ -104,6 +107,7 @@ public class ReadHistoryCommand extends BaseCommand {
} }
} }
} }
}
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
if (!history.bolusHistory.isEmpty()) { if (!history.bolusHistory.isEmpty()) {