TempBasal, TempTarget refactor; NonOverlapingIntervalsTest

This commit is contained in:
Milos Kozak 2018-03-26 22:37:53 +02:00
parent a4cb4cbbd5
commit cc436a09d9
18 changed files with 296 additions and 192 deletions

View file

@ -22,10 +22,6 @@ public abstract class Intervals<T extends Interval> {
rawData = new LongSparseArray<T>(); rawData = new LongSparseArray<T>();
} }
public Intervals(LongSparseArray<T> data) {
rawData = data;
}
public synchronized Intervals reset() { public synchronized Intervals reset() {
rawData = new LongSparseArray<T>(); rawData = new LongSparseArray<T>();
return this; return this;

View file

@ -58,7 +58,7 @@ import info.nightscout.utils.PercentageSplitter;
/** /**
* This Helper contains all resource to provide a central DB management functionality. Only methods handling * This Helper contains all resource to provide a central DB management functionality. Only methods handling
* data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL). * data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
* * <p>
* This class can safely be called from Services, but should not call Services to avoid circular dependencies. * This class can safely be called from Services, but should not call Services to avoid circular dependencies.
* One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all * One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all
* direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service. * direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service.
@ -893,14 +893,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void createTemptargetFromJsonIfNotExists(JSONObject trJson) { public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
try { try {
String units = MainApp.getConfigBuilder().getProfileUnits(); String units = MainApp.getConfigBuilder().getProfileUnits();
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = trJson.getLong("mills"); .date(trJson.getLong("mills"))
tempTarget.durationInMinutes = trJson.getInt("duration"); .duration(trJson.getInt("duration"))
tempTarget.low = Profile.toMgdl(trJson.getDouble("targetBottom"), units); .low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
tempTarget.high = Profile.toMgdl(trJson.getDouble("targetTop"), units); .high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
tempTarget.reason = trJson.getString("reason"); .reason(trJson.getString("reason"))
tempTarget._id = trJson.getString("_id"); ._id(trJson.getString("_id"))
tempTarget.source = Source.NIGHTSCOUT; .source(Source.NIGHTSCOUT);
createOrUpdate(tempTarget); createOrUpdate(tempTarget);
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
@ -1169,10 +1169,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} }
createOrUpdate(extendedBolus); createOrUpdate(extendedBolus);
} else { } else {
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = trJson.getLong("mills"); .date(trJson.getLong("mills"))
tempBasal.source = Source.NIGHTSCOUT; .source(Source.NIGHTSCOUT)
tempBasal.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0; .pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0);
if (trJson.has("duration")) { if (trJson.has("duration")) {
tempBasal.durationInMinutes = trJson.getInt("duration"); tempBasal.durationInMinutes = trJson.getInt("duration");
} }

View file

@ -91,6 +91,21 @@ public class TempTarget implements Interval {
return this; return this;
} }
public TempTarget reason(String reason) {
this.reason = reason;
return this;
}
public TempTarget _id(String _id) {
this._id = _id;
return this;
}
public TempTarget source(int source) {
this.source = source;
return this;
}
// -------- Interval interface --------- // -------- Interval interface ---------
Long cuttedEnd = null; Long cuttedEnd = null;

View file

@ -60,8 +60,36 @@ public class TemporaryBasal implements Interval {
public TemporaryBasal() { public TemporaryBasal() {
} }
public TemporaryBasal(long date) { public TemporaryBasal date(long date) {
this.date = date; this.date = date;
return this;
}
public TemporaryBasal duration(int durationInMinutes) {
this.durationInMinutes = durationInMinutes;
return this;
}
public TemporaryBasal absolute(double absoluteRate) {
this.absoluteRate = absoluteRate;
this.isAbsolute = true;
return this;
}
public TemporaryBasal percent(int percentRate) {
this.percentRate = percentRate;
this.isAbsolute = false;
return this;
}
public TemporaryBasal source(int source) {
this.source = source;
return this;
}
public TemporaryBasal pumpId(long pumpId) {
this.pumpId = pumpId;
return this;
} }
public TemporaryBasal(ExtendedBolus extendedBolus) { public TemporaryBasal(ExtendedBolus extendedBolus) {

View file

@ -701,17 +701,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
} else if (options.executeTempTarget) { } else if (options.executeTempTarget) {
try { try {
if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) { if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = eventTime.getTime(); .date(eventTime.getTime())
tempTarget.durationInMinutes = data.getInt("duration"); .duration(data.getInt("duration"))
tempTarget.reason = data.getString("reason"); .reason(data.getString("reason"))
tempTarget.source = Source.USER; .source(Source.USER);
if (tempTarget.durationInMinutes != 0) { if (tempTarget.durationInMinutes != 0) {
tempTarget.low = Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()); tempTarget.low(Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()))
tempTarget.high = Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()); .high(Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()));
} else { } else {
tempTarget.low = 0; tempTarget.low(0).high(0);
tempTarget.high = 0;
} }
log.debug("Creating new TempTarget db record: " + tempTarget.toString()); log.debug("Creating new TempTarget db record: " + tempTarget.toString());
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);

View file

@ -352,11 +352,10 @@ public class IobCobCalculatorPlugin implements PluginBase {
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) { if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) {
// Add expected zere temp basal for next 240 mins // Add expected zere temp basal for next 240 mins
IobTotal basalIobWithZeroTemp = basalIob.clone(); IobTotal basalIobWithZeroTemp = basalIob.clone();
TemporaryBasal t = new TemporaryBasal(); TemporaryBasal t = new TemporaryBasal()
t.date = now + 60 * 1000L; .date(now + 60 * 1000L)
t.durationInMinutes = 240; .duration(240)
t.isAbsolute = true; .absolute(0);
t.absoluteRate = 0;
if (t.date < time) { if (t.date < time) {
IobTotal calc = t.iobCalc(time); IobTotal calc = t.iobCalc(time);
basalIobWithZeroTemp.plus(calc); basalIobWithZeroTemp.plus(calc);

View file

@ -380,31 +380,31 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
accepted = true; accepted = true;
if (startActivityTTCheckbox.isChecked()) { if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = finalActivityTTDuration; .duration(finalActivityTTDuration)
tempTarget.reason = MainApp.gs(R.string.activity); .reason(MainApp.gs(R.string.activity))
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits()); .low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()))
tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits()); .high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} else if (startEatingSoonTTCheckbox.isChecked()) { } else if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = finalEatingSoonTTDuration; .duration(finalEatingSoonTTDuration)
tempTarget.reason = MainApp.gs(R.string.eatingsoon); .reason(MainApp.gs(R.string.eatingsoon))
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()); .low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()); .high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} else if (startHypoTTCheckbox.isChecked()) { } else if (startHypoTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = finalHypoTTDuration; .duration(finalHypoTTDuration)
tempTarget.reason = MainApp.gs(R.string.hypo); .reason(MainApp.gs(R.string.hypo))
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = Profile.toMgdl(finalHypoTT, currentProfile.getUnits()); .low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()))
tempTarget.high = Profile.toMgdl(finalHypoTT, currentProfile.getUnits()); .high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} }

View file

@ -281,13 +281,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
accepted = true; accepted = true;
if (startESMCheckbox.isChecked()) { if (startESMCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = (int) ttDuration; .duration((int) ttDuration)
tempTarget.reason = "Eating soon"; .reason("Eating soon")
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = (int) finalTT; .low((int) finalTT)
tempTarget.high = (int) finalTT; .high((int) finalTT);
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} }

View file

@ -109,10 +109,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
@NonNull @NonNull
private static final ComboPump pump = new ComboPump(); private static final ComboPump pump = new ComboPump();
/** This is used to determine when to pass a bolus cancel request to the scripter */ /**
* This is used to determine when to pass a bolus cancel request to the scripter
*/
private volatile boolean scripterIsBolusing; private volatile boolean scripterIsBolusing;
/** This is set to true to request a bolus cancellation. {@link #deliverBolus(DetailedBolusInfo)} /**
* will reset this flag. */ * This is set to true to request a bolus cancellation. {@link #deliverBolus(DetailedBolusInfo)}
* will reset this flag.
*/
private volatile boolean cancelBolus; private volatile boolean cancelBolus;
/** /**
@ -131,10 +135,12 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
*/ */
private volatile boolean pumpHistoryChanged = false; private volatile boolean pumpHistoryChanged = false;
/** Cache of the last <=2 boluses on the pump. Used to detect changes in pump history, /**
* Cache of the last <=2 boluses on the pump. Used to detect changes in pump history,
* requiring reading pump more history. This is read/set in {@link #checkHistory()} when changed * requiring reading pump more history. This is read/set in {@link #checkHistory()} when changed
* pump history was detected and was read, as well as in {@link #deliverBolus(DetailedBolusInfo)} * pump history was detected and was read, as well as in {@link #deliverBolus(DetailedBolusInfo)}
* after bolus delivery. Newest record is the first one. */ * after bolus delivery. Newest record is the first one.
*/
private volatile List<Bolus> recentBoluses = new ArrayList<>(0); private volatile List<Bolus> recentBoluses = new ArrayList<>(0);
public static ComboPlugin getPlugin() { public static ComboPlugin getPlugin() {
@ -373,7 +379,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return new Date(pump.lastSuccessfulCmdTime); return new Date(pump.lastSuccessfulCmdTime);
} }
/** Runs pump initializing if needed and reads the pump state from the main screen. */ /**
* Runs pump initializing if needed and reads the pump state from the main screen.
*/
@Override @Override
public synchronized void getPumpStatus() { public synchronized void getPumpStatus() {
log.debug("getPumpStatus called"); log.debug("getPumpStatus called");
@ -445,7 +453,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
MainApp.bus().post(new EventComboPumpUpdateGUI()); MainApp.bus().post(new EventComboPumpUpdateGUI());
} }
/** Updates local cache with state (reservoir level, last bolus ...) returned from the pump */ /**
* Updates local cache with state (reservoir level, last bolus ...) returned from the pump
*/
private void updateLocalData(CommandResult result) { private void updateLocalData(CommandResult result) {
if (result.reservoirLevel != PumpState.UNKNOWN) { if (result.reservoirLevel != PumpState.UNKNOWN) {
pump.reservoirLevel = result.reservoirLevel; pump.reservoirLevel = result.reservoirLevel;
@ -737,7 +747,8 @@ 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 - * @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 * there might be room for optimization to first test the currently running tbr
@ -804,12 +815,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
PumpState state = commandResult.state; PumpState state = commandResult.state;
if (state.tbrActive && state.tbrPercent == adjustedPercent if (state.tbrActive && state.tbrPercent == adjustedPercent
&& (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) { && (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) {
TemporaryBasal tempStart = new TemporaryBasal(); TemporaryBasal tempStart = new TemporaryBasal()
tempStart.date = state.timestamp; .date(state.timestamp)
tempStart.durationInMinutes = state.tbrRemainingDuration; .duration(state.tbrRemainingDuration)
tempStart.percentRate = state.tbrPercent; .percent(state.tbrPercent)
tempStart.isAbsolute = false; .source(Source.USER);
tempStart.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStart); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStart);
MainApp.bus().post(new EventComboPumpUpdateGUI()); MainApp.bus().post(new EventComboPumpUpdateGUI());
@ -825,7 +835,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return OPERATION_NOT_SUPPORTED; return OPERATION_NOT_SUPPORTED;
} }
/** Cancel an active Temp Basal. Mostly sets a fake Temp Basal to avoid a TBR CANCELLED /**
* Cancel an active Temp Basal. Mostly sets a fake Temp Basal to avoid a TBR CANCELLED
* alert. This relies on TemporaryBasal objects to properly reflect the pumps state, * alert. This relies on TemporaryBasal objects to properly reflect the pumps state,
* which is ensured by {@link #checkAndResolveTbrMismatch(PumpState)}, which runs on each * which is ensured by {@link #checkAndResolveTbrMismatch(PumpState)}, which runs on each
* connect. When a hard cancel is requested, the pump is queried for it's TBR state to * connect. When a hard cancel is requested, the pump is queried for it's TBR state to
@ -850,10 +861,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return new PumpEnactResult().success(false).enacted(false); return new PumpEnactResult().success(false).enacted(false);
} }
if (!cancelResult.state.tbrActive) { if (!cancelResult.state.tbrActive) {
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = cancelResult.state.timestamp; .date(cancelResult.state.timestamp)
tempBasal.durationInMinutes = 0; .duration(0)
tempBasal.source = Source.USER; .source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
return new PumpEnactResult().isTempCancel(true).success(true).enacted(true); return new PumpEnactResult().isTempCancel(true).success(true).enacted(true);
} else { } else {
@ -995,12 +1006,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
TemporaryBasal aapsTbr = MainApp.getConfigBuilder().getTempBasalFromHistory(now); TemporaryBasal aapsTbr = MainApp.getConfigBuilder().getTempBasalFromHistory(now);
if (aapsTbr == null || aapsTbr.percentRate != 0) { if (aapsTbr == null || aapsTbr.percentRate != 0) {
log.debug("Creating 15m zero temp since pump is suspended"); log.debug("Creating 15m zero temp since pump is suspended");
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = now; .date(now)
newTempBasal.percentRate = 0; .percent(0)
newTempBasal.isAbsolute = false; .duration(15)
newTempBasal.durationInMinutes = 15; .source(Source.USER);
newTempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
} }
} }
@ -1047,8 +1057,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
} }
} }
/** Check pump time (on the main menu) and raise notification if time is off. /**
* (setting clock is not supported by ruffy) */ * Check pump time (on the main menu) and raise notification if time is off.
* (setting clock is not supported by ruffy)
*/
private void checkPumpTime(PumpState state) { private void checkPumpTime(PumpState state) {
if (state.pumpTime == 0) { if (state.pumpTime == 0) {
// time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field) // time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field)
@ -1124,12 +1136,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "new TBR on pump")); .putCustomAttribute("type", "new TBR on pump"));
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = now; .date(now)
newTempBasal.percentRate = state.tbrPercent; .percent(state.tbrPercent)
newTempBasal.isAbsolute = false; .duration(state.tbrRemainingDuration)
newTempBasal.durationInMinutes = state.tbrRemainingDuration; .source(Source.USER);
newTempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
} else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) { } else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) {
log.debug("Ending AAPS-TBR since pump has no TBR active"); log.debug("Ending AAPS-TBR since pump has no TBR active");
@ -1137,10 +1148,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR cancelled on pump")); .putCustomAttribute("type", "TBR cancelled on pump"));
TemporaryBasal tempStop = new TemporaryBasal(); TemporaryBasal tempStop = new TemporaryBasal()
tempStop.date = now; .date(now)
tempStop.durationInMinutes = 0; .duration(0)
tempStop.source = Source.USER; .source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
} else if (aapsTbr != null && state.tbrActive } else if (aapsTbr != null && state.tbrActive
&& (aapsTbr.percentRate != state.tbrPercent || && (aapsTbr.percentRate != state.tbrPercent ||
@ -1150,23 +1161,24 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR on pump differs from AAPS TBR")); .putCustomAttribute("type", "TBR on pump differs from AAPS TBR"));
TemporaryBasal tempStop = new TemporaryBasal(); TemporaryBasal tempStop = new TemporaryBasal()
tempStop.date = now - 1000; .date(now - 1000)
tempStop.durationInMinutes = 0; .duration(0)
tempStop.source = Source.USER; .source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = now; .date(now)
newTempBasal.percentRate = state.tbrPercent; .percent(state.tbrPercent)
newTempBasal.isAbsolute = false; .duration(state.tbrRemainingDuration)
newTempBasal.durationInMinutes = state.tbrRemainingDuration; .source(Source.USER);
newTempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
} }
} }
/**Reads the pump's history and updates the DB accordingly. */ /**
* Reads the pump's history and updates the DB accordingly.
*/
private boolean readHistory(@Nullable 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) {
@ -1203,7 +1215,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return updated; return updated;
} }
/** Adds the bolus to the timestamp to be able to differentiate multiple boluses in the same /**
* Adds the bolus to the timestamp to be able to differentiate multiple boluses in the same
* minute. Best effort, since this covers only boluses up to 6.0 U and relies on other code * minute. Best effort, since this covers only boluses up to 6.0 U and relies on other code
* to prevent a boluses with the same amount to be delivered within the same minute. * to prevent a boluses with the same amount to be delivered within the same minute.
* Should be good enough, even with command mode, it's a challenge to create that situation * Should be good enough, even with command mode, it's a challenge to create that situation

View file

@ -68,33 +68,29 @@ public class MsgStatusTempBasal extends MessageBase {
if (danaRPump.isTempBasalInProgress) { if (danaRPump.isTempBasalInProgress) {
if (tempBasal.percentRate != danaRPump.tempBasalPercent) { if (tempBasal.percentRate != danaRPump.tempBasalPercent) {
// Close current temp basal // Close current temp basal
TemporaryBasal tempStop = new TemporaryBasal(danaRPump.tempBasalStart.getTime() - 1000); TemporaryBasal tempStop = new TemporaryBasal().date(danaRPump.tempBasalStart.getTime() - 1000).source(Source.USER);
tempStop.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(tempStop); treatmentsInterface.addToHistoryTempBasal(tempStop);
// Create new // Create new
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = danaRPump.tempBasalStart.getTime(); .date(danaRPump.tempBasalStart.getTime())
newTempBasal.percentRate = danaRPump.tempBasalPercent; .percent(danaRPump.tempBasalPercent)
newTempBasal.isAbsolute = false; .duration(danaRPump.tempBasalTotalSec / 60)
newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60; .source(Source.USER);
newTempBasal.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(newTempBasal); treatmentsInterface.addToHistoryTempBasal(newTempBasal);
} }
} else { } else {
// Close current temp basal // Close current temp basal
TemporaryBasal tempStop = new TemporaryBasal(now); TemporaryBasal tempStop = new TemporaryBasal().date(now).source(Source.USER);
tempStop.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(tempStop); treatmentsInterface.addToHistoryTempBasal(tempStop);
} }
} else { } else {
if (danaRPump.isTempBasalInProgress) { if (danaRPump.isTempBasalInProgress) {
// Create new // Create new
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = danaRPump.tempBasalStart.getTime(); .date(danaRPump.tempBasalStart.getTime())
newTempBasal.percentRate = danaRPump.tempBasalPercent; .percent(danaRPump.tempBasalPercent)
newTempBasal.isAbsolute = false; .duration(danaRPump.tempBasalTotalSec / 60)
newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60; .source(Source.USER);
newTempBasal.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(newTempBasal); treatmentsInterface.addToHistoryTempBasal(newTempBasal);
} }
} }

View file

@ -85,10 +85,7 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet {
int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF00) + (intFromBuff(data, 8, 1) & 0xFF); int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF00) + (intFromBuff(data, 8, 1) & 0xFF);
int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF); int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF);
TemporaryBasal temporaryBasal = new TemporaryBasal(); TemporaryBasal temporaryBasal = new TemporaryBasal().date(datetime.getTime()).source(Source.PUMP).pumpId(datetime.getTime());
temporaryBasal.date = datetime.getTime();
temporaryBasal.source = Source.PUMP;
temporaryBasal.pumpId = datetime.getTime();
ExtendedBolus extendedBolus = new ExtendedBolus(); ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime(); extendedBolus.date = datetime.getTime();

View file

@ -56,10 +56,10 @@ public class MsgHistoryEvents_v2 extends MessageBase {
int param1 = intFromBuff(bytes, 7, 2); int param1 = intFromBuff(bytes, 7, 2);
int param2 = intFromBuff(bytes, 9, 2); int param2 = intFromBuff(bytes, 9, 2);
TemporaryBasal temporaryBasal = new TemporaryBasal(); TemporaryBasal temporaryBasal = new TemporaryBasal()
temporaryBasal.date = datetime.getTime(); .date(datetime.getTime())
temporaryBasal.source = Source.PUMP; .source(Source.PUMP)
temporaryBasal.pumpId = datetime.getTime(); .pumpId(datetime.getTime());
ExtendedBolus extendedBolus = new ExtendedBolus(); ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime(); extendedBolus.date = datetime.getTime();

View file

@ -592,12 +592,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
if (pumpEnactResult.success) { if (pumpEnactResult.success) {
// create log entry // create log entry
final TemporaryBasal tempBasal = new TemporaryBasal(); final TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = false; .percent(percent_amount)
tempBasal.percentRate = percent_amount; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER);
tempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
} }
@ -643,12 +642,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
if (pumpEnactResult.success) { if (pumpEnactResult.success) {
// create log entry // create log entry
final TemporaryBasal tempBasal = new TemporaryBasal(); final TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = false; .percent(percent)
tempBasal.percentRate = percent; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER); // TODO check this is correct
tempBasal.source = Source.USER; // TODO check this is correct
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
} }
@ -683,13 +681,10 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
} }
// TODO isn't conditional on one apparently being in progress only the history change // TODO isn't conditional on one apparently being in progress only the history change
boolean enacted = false;
final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME);
if (MainApp.getConfigBuilder().isTempBasalInProgress()) { if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
enacted = true; TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis());
tempStop.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
} }
lastDataTime = new Date(); lastDataTime = new Date();

View file

@ -10,9 +10,8 @@ import info.nightscout.androidaps.db.TemporaryBasal;
/** /**
* Created by jamorham on 27/01/2018. * Created by jamorham on 27/01/2018.
* * <p>
* Write to the History Log * Write to the History Log
*
*/ */
class HistoryLogAdapter { class HistoryLogAdapter {
@ -25,7 +24,7 @@ class HistoryLogAdapter {
void createTBRrecord(Date eventDate, int percent, int duration, long record_id) { void createTBRrecord(Date eventDate, int percent, int duration, long record_id) {
TemporaryBasal temporaryBasal = new TemporaryBasal(eventDate.getTime()); TemporaryBasal temporaryBasal = new TemporaryBasal().date(eventDate.getTime());
final TemporaryBasal temporaryBasalFromHistory = MainApp.getConfigBuilder().getTempBasalFromHistory(eventDate.getTime()); final TemporaryBasal temporaryBasalFromHistory = MainApp.getConfigBuilder().getTempBasalFromHistory(eventDate.getTime());
@ -50,10 +49,10 @@ class HistoryLogAdapter {
} }
} }
temporaryBasal.source = Source.PUMP; temporaryBasal.source(Source.PUMP)
temporaryBasal.pumpId = record_id; .pumpId(record_id)
temporaryBasal.percentRate = percent; .percent(percent)
temporaryBasal.durationInMinutes = duration; .duration(duration);
MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal);
} }

View file

@ -291,12 +291,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
@Override @Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) {
TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder();
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = true; .absolute(absoluteRate)
tempBasal.absoluteRate = absoluteRate; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER);
tempBasal.source = Source.USER;
PumpEnactResult result = new PumpEnactResult(); PumpEnactResult result = new PumpEnactResult();
result.success = true; result.success = true;
result.enacted = true; result.enacted = true;
@ -321,12 +320,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
if (!result.success) if (!result.success)
return result; return result;
} }
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = false; .percent(percent)
tempBasal.percentRate = percent; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER);
tempBasal.source = Source.USER;
result.success = true; result.success = true;
result.enacted = true; result.enacted = true;
result.percent = percent; result.percent = percent;
@ -376,8 +374,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (treatmentsInterface.isTempBasalInProgress()) { if (treatmentsInterface.isTempBasalInProgress()) {
result.enacted = true; result.enacted = true;
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
tempStop.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(tempStop); treatmentsInterface.addToHistoryTempBasal(tempStop);
//tempBasal = null; //tempBasal = null;
if (Config.logPumpComm) if (Config.logPumpComm)

View file

@ -604,17 +604,15 @@ public class ActionStringHandler {
} }
private static void generateTempTarget(int duration, double low, double high) { private static void generateTempTarget(int duration, double low, double high) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = duration; .duration(duration)
tempTarget.reason = "WearPlugin"; .reason("WearPlugin")
tempTarget.source = Source.USER; .source(Source.USER);
if (tempTarget.durationInMinutes != 0) { if (tempTarget.durationInMinutes != 0) {
tempTarget.low = low; tempTarget.low(low).high(high);
tempTarget.high = high;
} else { } else {
tempTarget.low = 0; tempTarget.low(0).high(0);
tempTarget.high = 0;
} }
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);

View file

@ -0,0 +1,49 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class NonOverapingIntervalsTest {
private final long startDate = DateUtil.now();
NonOverlappingIntervals<TemporaryBasal> list = new NonOverlappingIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new TemporaryBasal().date(startDate).duration((int) T.hours(10).mins()).absolute(1));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// stop temp after 5h
list.add(new TemporaryBasal().date(startDate + T.hours(5).msecs()).duration(0));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(1d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// insert 1h interval inside
list.add(new TemporaryBasal().date(startDate + T.hours(3).msecs()).duration((int) T.hours(1).mins()).absolute(2));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() - 1));
Assert.assertEquals(2d, list.getValueByInterval(startDate + T.hours(3).msecs()).absoluteRate, 0.01d);
Assert.assertEquals(2d, list.getValueByInterval(startDate + T.hours(4).msecs() - 1).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(4).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
}
}

View file

@ -5,6 +5,9 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T; import info.nightscout.utils.T;
@ -46,4 +49,24 @@ public class OverapingIntervalsTest {
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1)); Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
} }
@Test
public void testCopyConstructor() {
list.reset();
list.add(new TempTarget().date(startDate).duration((int) T.hours(10).mins()).low(100).high(100));
OverlappingIntervals<TempTarget> list2 = new OverlappingIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
@Test
public void testReversingArrays() {
List<TempTarget> someList = new ArrayList<>();
someList.add(new TempTarget().date(startDate).duration((int) T.hours(3).mins()).low(200).high(200));
someList.add(new TempTarget().date(startDate + T.hours(1).msecs()).duration((int) T.hours(1).mins()).low(100).high(100));
list.reset();
list.add(someList);
Assert.assertEquals(startDate, list.get(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversedList().get(0).date);
}
} }