Stuff:
* Read all history * Simple viewer for TDDs, errors * Clean up cancelling TBR (incomplete) * Initializing pump robustness
This commit is contained in:
parent
3072a42cd7
commit
c11086d9ea
16 changed files with 278 additions and 104 deletions
|
@ -73,6 +73,3 @@ Usage
|
|||
have to wait till the pump's display turns off before it can reconnect to the pump).
|
||||
If the pump's alarm continues, the last action might have failed, in which case the user needs to confirm the alarm
|
||||
|
||||
v3 TODOs
|
||||
- Reading and displaying TDDs
|
||||
|
||||
|
|
|
@ -8,10 +8,21 @@
|
|||
- [ ] Bolus deleted in treatments (marked invalid?!) is re-added when pump reads history
|
||||
- [ ] Tasks
|
||||
- [ ] Main
|
||||
- [ ] on command error: recover by returning to main menu
|
||||
- [ ] Reading history
|
||||
- [ ] Bolus
|
||||
- [x] Bolus
|
||||
- [x] Read
|
||||
- [x] Sync DB
|
||||
- [ ] TBRs
|
||||
- [x] Read
|
||||
- [ ] Sync DB
|
||||
- [ ] Alerts
|
||||
- [x] Read
|
||||
- [ ] Sync DB?
|
||||
- [x] Display in UI
|
||||
- [ ] TDD
|
||||
- [x] Read
|
||||
- [ ] Sync DB?
|
||||
- [ ] Display in UI
|
||||
- [ ] Taking over alerts
|
||||
- [ ] On connect
|
||||
|
@ -24,6 +35,7 @@
|
|||
- [ ] Run readReservoirAndBolusLevel after SetTbr too so boluses on the pump are caught sooner?
|
||||
Currently the pump gets to know such a record when bolusing or when refresh() is called
|
||||
after 15m of no other command taking place. IOB will then be current with next loop
|
||||
- [ ] Optimize reading full history to pass timestamps of last known records to avoid reading known records
|
||||
iteration.
|
||||
- [ ] Cleanups
|
||||
- [ ] Finish 'enacted' removal rewrite (esp. cancel tbr)
|
||||
|
@ -39,6 +51,8 @@
|
|||
- [ ] Display errors in combo tap
|
||||
- [x] Option to raise overview notifications as android notification with noise (for urgent ones?)
|
||||
- [ ] Low prio
|
||||
- [ ] Naming is messed up: pump has warnings and errors, which cause alerts; W+E are thus alerts,
|
||||
e.g. pumpErrorHistory should be renamed to alertHistory
|
||||
- [ ] Enable BT if disabled? does dana does this?
|
||||
- [ ] Finish and test German translation
|
||||
- [ ] No clean startup/shutdown; RuffyScripter is instanciated once, idle disconnect thread never killed
|
||||
|
@ -46,12 +60,6 @@
|
|||
Android logs it as crashed and restarts it, thereby restarting the app (or just keeping it alive,
|
||||
also causes errors with the DB as there were attemtps to open a closed DB instance/ref.
|
||||
|
||||
- [ ] v3
|
||||
- [ ] Tasks (this is probably best left to the command-mode people)
|
||||
- [ ] Reading TDD
|
||||
- [ ] UI for TDDs
|
||||
- [ ] Optimize reading full history to pass timestamps of last known records to avoid reading known records
|
||||
|
||||
Inbox
|
||||
- [ ] Where/when to call checkTbrMisMatch?
|
||||
- [ ] pairing: just start SetupFragment?
|
||||
|
|
|
@ -53,6 +53,9 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
|
|||
Button errorHistory = (Button) view.findViewById(R.id.combo_error_history);
|
||||
errorHistory.setOnClickListener(this);
|
||||
|
||||
Button tddHistory = (Button) view.findViewById(R.id.combo_tdd_history);
|
||||
tddHistory.setOnClickListener(this);
|
||||
|
||||
updateGUI();
|
||||
return view;
|
||||
}
|
||||
|
@ -65,8 +68,11 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
|
|||
break;
|
||||
case R.id.combo_error_history:
|
||||
ComboErrorHistoryDialog ehd = new ComboErrorHistoryDialog();
|
||||
FragmentManager manager = getFragmentManager();
|
||||
ehd.show(manager, ComboErrorHistoryDialog.class.getSimpleName());
|
||||
ehd.show(getFragmentManager(), ComboErrorHistoryDialog.class.getSimpleName());
|
||||
break;
|
||||
case R.id.combo_tdd_history:
|
||||
ComboTddHistoryDialog thd = new ComboTddHistoryDialog();
|
||||
thd.show(getFragmentManager(), ComboTddHistoryDialog.class.getSimpleName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ import de.jotomo.ruffy.spi.CommandResult;
|
|||
import de.jotomo.ruffy.spi.PumpState;
|
||||
import de.jotomo.ruffy.spi.RuffyCommands;
|
||||
import de.jotomo.ruffy.spi.history.Bolus;
|
||||
import de.jotomo.ruffy.spi.history.PumpError;
|
||||
import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
|
||||
import de.jotomo.ruffy.spi.history.Tbr;
|
||||
import de.jotomo.ruffy.spi.history.Tdd;
|
||||
import de.jotomo.ruffyscripter.RuffyCommandsV1Impl;
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
|
@ -38,6 +40,7 @@ import info.nightscout.androidaps.interfaces.PluginBase;
|
|||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Notification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
|
||||
|
@ -243,24 +246,35 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
}
|
||||
}
|
||||
|
||||
CommandResult stateResult = runCommand("Refreshing", 3, ruffyScripter::readReservoirLevelAndLastBolus);
|
||||
CommandResult stateResult = runCommand(pump.initialized ? MainApp.sResources.getString(R.string.combo_pump_action_refreshing) : MainApp.sResources.getString(R.string.combo_pump_action_initializing),
|
||||
1, ruffyScripter::readReservoirLevelAndLastBolus);
|
||||
if (!stateResult.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkForTbrMismatch(stateResult.state);
|
||||
|
||||
int minutesOfDayNow = Calendar.getInstance().get(Calendar.HOUR) + Calendar.getInstance().get(Calendar.MINUTE) * 60;
|
||||
if (!pump.initialized || (Math.abs(stateResult.state.pumpTimeMinutesOfDay - minutesOfDayNow) >= 2)) {
|
||||
runCommand("Updating pump clock", 2, ruffyScripter::setDateAndTime);
|
||||
if (!runCommand("Updating pump clock", 2, ruffyScripter::setDateAndTime).success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pump.initialized) {
|
||||
runCommand("Reading basal profile", 2, ruffyScripter::readBasalProfile);
|
||||
if (!runCommand("Reading basal profile", 2, ruffyScripter::readBasalProfile).success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
checkPumpHistory();
|
||||
if (!checkPumpHistory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if (!pump.initialized) {
|
||||
// pump.initialized = clockUpdated && basalProfileRead;
|
||||
// }
|
||||
pump.initialized = true;
|
||||
// ComboFragment updates state fully only after the pump has initialized,
|
||||
// this fetches state again and updates the ui proper
|
||||
runCommand(null, 0, ruffyScripter::readPumpState);
|
||||
}
|
||||
|
||||
|
||||
|
@ -504,11 +518,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
PumpState state = commandResult.state;
|
||||
if (state.tbrActive && state.tbrPercent == percent
|
||||
&& (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) {
|
||||
// TODO timestamp: can this cause problems? setting TBR while a minute flips over?
|
||||
// might that be the cause if the TBR duration instantly flips from e.g. 0:30 -> 0:29 ?
|
||||
TemporaryBasal tempStart = new TemporaryBasal(state.timestamp);
|
||||
// TODO commandResult.state.tbrRemainingDuration might already display 29 if 30 was set, since 29:59 is shown as 29 ...
|
||||
// we should check this, but really ... something must be really screwed up if that number was anything different
|
||||
// TODO actually ... might setting 29 help with gaps between TBRs? w/o the hack in TemporaryBasal?
|
||||
// nah, fucks up duration in treatment history
|
||||
tempStart.durationInMinutes = durationInMinutes;
|
||||
tempStart.percentRate = adjustedPercent;
|
||||
tempStart.isAbsolute = false;
|
||||
|
@ -529,78 +543,53 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
return OPERATION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// TODO clean this method up:
|
||||
// check PumpState to verify TBR has been cancelled.
|
||||
// enacted field.
|
||||
// TODO review and test, esp. aaps/pump mismatch situations
|
||||
@Override
|
||||
public PumpEnactResult cancelTempBasal(boolean userRequested) {
|
||||
log.debug("cancelTempBasal called");
|
||||
|
||||
CommandResult commandResult = null;
|
||||
TemporaryBasal tempBasal = null;
|
||||
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
||||
|
||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
||||
// checkForTbrMismatch();
|
||||
|
||||
if (activeTemp == null || userRequested) {
|
||||
// TODO
|
||||
/* v1 compatibility to sync DB to pump if they diverged (activeTemp == null) */
|
||||
log.debug("cancelTempBasal: hard-cancelling TBR since user requested");
|
||||
commandResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_cancelling_tbr), 2, ruffyScripter::cancelTbr);
|
||||
CommandResult commandResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_cancelling_tbr), 2, ruffyScripter::cancelTbr);
|
||||
|
||||
if (!commandResult.state.tbrActive) {
|
||||
tempBasal = new TemporaryBasal(System.currentTimeMillis());
|
||||
TemporaryBasal tempBasal = new TemporaryBasal(System.currentTimeMillis());
|
||||
tempBasal.durationInMinutes = 0;
|
||||
tempBasal.source = Source.USER;
|
||||
pumpEnactResult.isTempCancel = true;
|
||||
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
|
||||
return new PumpEnactResult().isTempCancel(true).success(true).enacted(true);
|
||||
} else {
|
||||
return new PumpEnactResult().success(false).enacted(false);
|
||||
}
|
||||
} else if ((activeTemp.percentRate >= 90 && activeTemp.percentRate <= 110) && activeTemp.getPlannedRemainingMinutes() <= 15) {
|
||||
// Let fake neutral temp keep run (see below)
|
||||
log.debug("cancelTempBasal: skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins.");
|
||||
pumpEnactResult.comment = "cancelTempBasal skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins.";
|
||||
// TODO check what AAPS does with this; no DB update is required;
|
||||
// looking at info/nightscout/androidaps/plugins/Loop/LoopPlugin.java:280
|
||||
// both values are used as one:
|
||||
// if (applyResult.enacted || applyResult.success) { ...
|
||||
pumpEnactResult.enacted = true; // all fine though...
|
||||
pumpEnactResult.success = true; // just roll with it...
|
||||
return new PumpEnactResult().success(true).enacted(true)
|
||||
.comment("cancelTempBasal skipping changing tbr since it already is at "
|
||||
+ activeTemp.percentRate + "% and running for another "
|
||||
+ activeTemp.getPlannedRemainingMinutes() + " mins.");
|
||||
} else {
|
||||
// Set a fake neutral temp to avoid TBR cancel alert. Decide 90% vs 110% based on
|
||||
// on whether the TBR we're cancelling is above or below 100%.
|
||||
final int percentage = (activeTemp.percentRate > 100) ? 110 : 90;
|
||||
log.debug("cancelTempBasal: changing TBR to " + percentage + "% for 15 mins.");
|
||||
commandResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_cancelling_tbr), 2, () -> ruffyScripter.setTbr(percentage, 15));
|
||||
CommandResult commandResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_cancelling_tbr), 2, () -> ruffyScripter.setTbr(percentage, 15));
|
||||
|
||||
// TODO properly check fake neutral temp is active
|
||||
// if (!commandResult.state.tbrActive) {
|
||||
if (commandResult.success) {
|
||||
tempBasal = new TemporaryBasal(System.currentTimeMillis());
|
||||
if (commandResult.state.tbrActive && commandResult.state.tbrPercent == percentage
|
||||
&& (commandResult.state.tbrRemainingDuration == 15 || commandResult.state.tbrRemainingDuration == 14)) {
|
||||
TemporaryBasal tempBasal = new TemporaryBasal(System.currentTimeMillis());
|
||||
tempBasal.durationInMinutes = 15;
|
||||
tempBasal.source = Source.USER;
|
||||
tempBasal.percentRate = percentage;
|
||||
tempBasal.isAbsolute = false;
|
||||
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
|
||||
return new PumpEnactResult().success(true).enacted(true);
|
||||
} else {
|
||||
return new PumpEnactResult().success(false).enacted(false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO properly check pumpstate to confirm cancellation
|
||||
// PumpState state = commandResult.state;
|
||||
// if (!state.tbrActive && state.tbrPercent == percent
|
||||
// && (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
if (tempBasal != null) {
|
||||
ConfigBuilderPlugin treatmentsInterface = MainApp.getConfigBuilder();
|
||||
treatmentsInterface.addToHistoryTempBasal(tempBasal);
|
||||
}
|
||||
|
||||
if (commandResult != null) {
|
||||
pumpEnactResult.success = commandResult.success;
|
||||
pumpEnactResult.enacted = true;
|
||||
}
|
||||
return pumpEnactResult;
|
||||
}
|
||||
|
||||
private interface CommandExecution {
|
||||
|
@ -609,6 +598,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
|
||||
// TODO remove this method, make stuff explicit (state updates, activity updates)
|
||||
// and only have a withRetries() method that simply retries a command?
|
||||
|
||||
/**
|
||||
* Runs a command, sets an activity if provided, retries if requested and updates fields
|
||||
* concerned with last connection.
|
||||
|
@ -663,7 +653,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
if (commandResult.state.unsafeUsageDetected) {
|
||||
lastViolation = System.currentTimeMillis();
|
||||
}
|
||||
if (commandResult.lastBolus != null && !commandResult.lastBolus.isValid) {
|
||||
if (commandResult.lastBolus != null && !commandResult.lastBolus.isValid) {
|
||||
lastViolation = commandResult.lastBolus.timestamp;
|
||||
} else if (commandResult.history != null) {
|
||||
for (Bolus bolus : commandResult.history.bolusHistory) {
|
||||
|
@ -687,7 +677,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
}
|
||||
}
|
||||
|
||||
/** Checks the main screen to determine if TBR on pump matches app state. */
|
||||
/**
|
||||
* Checks the main screen to determine if TBR on pump matches app state.
|
||||
*/
|
||||
private boolean checkForTbrMismatch(PumpState state) {
|
||||
// detectTbrMismatch(): 'quick' check with no overhead on the pump side
|
||||
// TODO check if this works with pump suspend, esp. around pump suspend there'll be syncing to do;
|
||||
|
@ -736,20 +728,18 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
new PumpHistoryRequest()
|
||||
.bolusHistory(PumpHistoryRequest.LAST)
|
||||
.tbrHistory(PumpHistoryRequest.LAST)
|
||||
.errorHistory(PumpHistoryRequest.LAST)));
|
||||
.pumpErrorHistory(PumpHistoryRequest.LAST)));
|
||||
|
||||
if (!commandResult.success || commandResult.history == null) {
|
||||
// TODO error case, command
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO opt, construct PumpHistoryRequest to requset only what needs updating
|
||||
boolean syncNeeded = false;
|
||||
// TODO v2.1 optimize, construct PumpHistoryRequest to requset only what needs updating
|
||||
PumpHistoryRequest request = new PumpHistoryRequest();
|
||||
|
||||
// last bolus
|
||||
List<Treatment> treatments = MainApp.getConfigBuilder().getTreatmentsFromHistory();
|
||||
// Collections.reverse(treatments);
|
||||
Treatment aapsBolus = null;
|
||||
for (Treatment t : treatments) {
|
||||
if (t.insulin != 0) {
|
||||
|
@ -766,7 +756,6 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
if ((aapsBolus == null || pumpBolus == null)
|
||||
|| (Math.abs(aapsBolus.insulin - pumpBolus.amount) > 0.05 || aapsBolus.date != pumpBolus.timestamp)) {
|
||||
log.debug("Last bolus on pump is unknown, refreshing full bolus history");
|
||||
syncNeeded = true;
|
||||
request.bolusHistory = PumpHistoryRequest.FULL;
|
||||
}
|
||||
|
||||
|
@ -782,30 +771,40 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
pumpTbr = tbrHistory.get(0);
|
||||
}
|
||||
if ((aapsTbr == null || pumpTbr == null)
|
||||
|| (aapsTbr.percentRate != pumpTbr.percent || aapsTbr.durationInMinutes != pumpTbr.duration)) {
|
||||
// TODO
|
||||
// log.debug("Last TBR on pump is unknown, refreshing full TBR history");
|
||||
// syncNeeded = true;
|
||||
// request.tbrHistory = PumpHistoryRequest.FULL;
|
||||
|| (aapsTbr.date != pumpTbr.timestamp || aapsTbr.percentRate != pumpTbr.percent || aapsTbr.durationInMinutes != pumpTbr.duration)) {
|
||||
log.debug("Last TBR on pump is unknown, refreshing full TBR history");
|
||||
request.tbrHistory = PumpHistoryRequest.FULL;
|
||||
}
|
||||
|
||||
// last error
|
||||
// TODO add DB table ... or just keep in memory? does android allow that (fragment kill frenzy) without workarounds?
|
||||
// is comboplugin a service or a class with statics?
|
||||
// request.pumpErrorHistory = PumpHistoryRequest.FULL;
|
||||
PumpError aapsError = null;
|
||||
if (!pump.history.pumpErrorHistory.isEmpty()) {
|
||||
aapsError = pump.history.pumpErrorHistory.get(0);
|
||||
}
|
||||
PumpError pumpError = null;
|
||||
List<PumpError> pumpErrorHistory = commandResult.history.pumpErrorHistory;
|
||||
if (!pumpErrorHistory.isEmpty()){
|
||||
pumpError = pumpErrorHistory.get(0);
|
||||
}
|
||||
if ((aapsError == null || pumpError == null)
|
||||
|| aapsError.timestamp != pumpError.timestamp) {
|
||||
log.debug("Last pump error is unknown, refrehing full error history");
|
||||
}
|
||||
|
||||
// tdd
|
||||
// TODO; ... just fetch them on-deamand when the user opens the fragment?
|
||||
// TODO v2.1
|
||||
|
||||
|
||||
if (syncNeeded) {
|
||||
syncHistory(request);
|
||||
if (request.bolusHistory != PumpHistoryRequest.SKIP
|
||||
|| request.tbrHistory != PumpHistoryRequest.SKIP
|
||||
|| request.pumpErrorHistory != PumpHistoryRequest.SKIP
|
||||
|| request.tddHistory != PumpHistoryRequest.SKIP) {
|
||||
readHistory(request);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void syncHistory(final PumpHistoryRequest request) {
|
||||
private void readHistory(final PumpHistoryRequest request) {
|
||||
CommandResult result = runCommand(MainApp.sResources.getString(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request));
|
||||
if (!result.success) {
|
||||
// TODO
|
||||
|
@ -833,20 +832,28 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
|
|||
// TODO tolerance for start/end deviations? temp start is based on pump time, but in ms; round to seconds, so we can find it here more easily?
|
||||
|
||||
// errors
|
||||
// TODO
|
||||
for (PumpError pumpError : result.history.pumpErrorHistory) {
|
||||
if (!pump.history.pumpErrorHistory.contains(pumpError)) {
|
||||
pump.history.pumpErrorHistory.add(pumpError);
|
||||
}
|
||||
}
|
||||
|
||||
// tdd
|
||||
// TODO v3
|
||||
for (Tdd tdd : result.history.tddHistory) {
|
||||
if (!pump.history.tddHistory.contains(tdd)) {
|
||||
pump.history.tddHistory.add(tdd);
|
||||
}
|
||||
}
|
||||
|
||||
// fetch state (updates local state as well)
|
||||
runCommand(null, 3, ruffyScripter::readReservoirLevelAndLastBolus);
|
||||
}
|
||||
|
||||
void forceSyncFullHistory() {
|
||||
syncHistory(new PumpHistoryRequest()
|
||||
void forceFullHistoryRead() {
|
||||
// TODO v2.1: optimize to pass timestamps of last known records to avoid reading known records
|
||||
readHistory(new PumpHistoryRequest()
|
||||
.bolusHistory(PumpHistoryRequest.FULL)
|
||||
.tbrHistory(PumpHistoryRequest.FULL)
|
||||
.errorHistory(PumpHistoryRequest.FULL)
|
||||
.pumpErrorHistory(PumpHistoryRequest.FULL)
|
||||
.tddHistory(PumpHistoryRequest.FULL));
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import android.support.annotation.NonNull;
|
|||
import android.support.annotation.Nullable;
|
||||
|
||||
import de.jotomo.ruffy.spi.BasalProfile;
|
||||
import de.jotomo.ruffy.spi.PumpState;
|
||||
import de.jotomo.ruffy.spi.CommandResult;
|
||||
import de.jotomo.ruffy.spi.PumpState;
|
||||
import de.jotomo.ruffy.spi.history.Bolus;
|
||||
import de.jotomo.ruffy.spi.history.PumpHistory;
|
||||
|
||||
|
@ -28,6 +28,8 @@ class ComboPump {
|
|||
volatile BasalProfile basalProfile;
|
||||
@NonNull
|
||||
volatile PumpHistory history = new PumpHistory();
|
||||
/** Time the active TBR was set (if any). Needed to calculate remaining time in fragment */
|
||||
/**
|
||||
* Time the active TBR was set (if any). Needed to calculate remaining time in fragment
|
||||
*/
|
||||
long tbrSetTime;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCombo;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
|
||||
import de.jotomo.ruffy.spi.history.Tdd;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
/**
|
||||
* Created by adrian on 17/08/17.
|
||||
*/
|
||||
|
||||
public class ComboTddHistoryDialog extends DialogFragment {
|
||||
private static Logger log = LoggerFactory.getLogger(ComboTddHistoryDialog.class);
|
||||
|
||||
private TextView text;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.combo_tdd_history_fragment, container, false);
|
||||
text = (TextView) layout.findViewById(R.id.combo_tdd_history_text);
|
||||
List<Tdd> tdds = ComboPlugin.getPlugin().getPump().history.tddHistory;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM");
|
||||
if (tdds.isEmpty()) {
|
||||
text.setText("No TDDs. To retrieve the TDD history from the pump, long press the Refresh button.");
|
||||
} else {
|
||||
for (Tdd tdd : tdds) {
|
||||
sb.append(simpleDateFormat.format(tdd.timestamp));
|
||||
sb.append(" ");
|
||||
sb.append(tdd.total);
|
||||
sb.append("\n");
|
||||
}
|
||||
text.setText(sb.toString());
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".plugins.ProfileNS.NSProfileFragment">
|
||||
tools:context=".plugins.PumpCombo.ComboFragment">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="info.nightscout.androidaps.plugins.PumpCombo.activities.PairingActivity">
|
||||
tools:context=".plugins.PumpCombo.activities.PairingActivity">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/combo_pairing_listview"
|
||||
|
|
27
app/src/main/res/layout/combo_tdd_history_fragment.xml
Normal file
27
app/src/main/res/layout/combo_tdd_history_fragment.xml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".plugins.PumpCombo.ComboFragment">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/combo_tdd_history_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="textStart"
|
||||
android:padding="10dp"
|
||||
android:gravity="start"/>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</FrameLayout>
|
|
@ -373,6 +373,17 @@
|
|||
android:paddingRight="0dp"
|
||||
android:text="@string/pump_errors_history" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/combo_tdd_history"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/icon_danarstats"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="@string/combo_stats" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package de.jotomo.ruffy.spi.history;
|
||||
|
||||
public class PumpError extends HistoryRecord {
|
||||
/** Code is an E for error or W for warning, followed by a single digit, e.g. W7 (TBR cancelled). */
|
||||
// public final String code;
|
||||
public final Integer warningCode;
|
||||
|
||||
|
||||
public final Integer errorCode;
|
||||
/** Error message, in the language configured on the pump. */
|
||||
public final String message;
|
||||
|
@ -17,6 +13,30 @@ public class PumpError extends HistoryRecord {
|
|||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
PumpError pumpError = (PumpError) o;
|
||||
|
||||
if (timestamp != pumpError.timestamp) return false;
|
||||
if (warningCode != null ? !warningCode.equals(pumpError.warningCode) : pumpError.warningCode != null)
|
||||
return false;
|
||||
if (errorCode != null ? !errorCode.equals(pumpError.errorCode) : pumpError.errorCode != null)
|
||||
return false;
|
||||
return message != null ? message.equals(pumpError.message) : pumpError.message == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (timestamp ^ (timestamp >>> 32));
|
||||
result = 31 * result + (warningCode != null ? warningCode.hashCode() : 0);
|
||||
result = 31 * result + (errorCode != null ? errorCode.hashCode() : 0);
|
||||
result = 31 * result + (message != null ? message.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PumpError{" +
|
||||
|
|
|
@ -3,6 +3,7 @@ package de.jotomo.ruffy.spi.history;
|
|||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/** History data as read from the pump's My Data menu.
|
||||
|
@ -13,7 +14,7 @@ public class PumpHistory {
|
|||
@NonNull
|
||||
public List<Tbr> tbrHistory = new ArrayList<>();
|
||||
@NonNull
|
||||
public List<PumpError> pumpErrorHistory = new ArrayList<>();
|
||||
public List<PumpError> pumpErrorHistory = new LinkedList<>();
|
||||
@NonNull
|
||||
public List<Tdd> tddHistory = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ public class PumpHistoryRequest {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PumpHistoryRequest errorHistory(long errorHistory) {
|
||||
this.pumpErrorHistory = errorHistory;
|
||||
public PumpHistoryRequest pumpErrorHistory(long pumpErrorHistory) {
|
||||
this.pumpErrorHistory = pumpErrorHistory;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.jotomo.ruffy.spi.history;
|
||||
|
||||
/** Note: the timestamp is the time the TBR **ended**, not started .*/
|
||||
public class Tbr extends HistoryRecord {
|
||||
public final int duration;
|
||||
public final int percent;
|
||||
|
@ -10,6 +11,26 @@ public class Tbr extends HistoryRecord {
|
|||
this.percent = percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Tbr tbr = (Tbr) o;
|
||||
|
||||
if (timestamp != tbr.timestamp) return false;
|
||||
if (duration != tbr.duration) return false;
|
||||
return percent == tbr.percent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (timestamp ^ (timestamp >>> 32));
|
||||
result = 31 * result + duration;
|
||||
result = 31 * result + percent;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tbr{" +
|
||||
|
|
|
@ -9,6 +9,27 @@ public class Tdd extends HistoryRecord {
|
|||
this.total = total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Tdd tdd = (Tdd) o;
|
||||
|
||||
if (timestamp != tdd.timestamp) return false;
|
||||
return Double.compare(tdd.total, total) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
result = (int) (timestamp ^ (timestamp >>> 32));
|
||||
temp = Double.doubleToLongBits(total);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tdd{" +
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import de.jotomo.ruffy.spi.history.Bolus;
|
||||
|
@ -156,7 +157,11 @@ public class ReadHistoryCommand extends BaseCommand {
|
|||
private Tdd readTddRecord() {
|
||||
scripter.verifyMenuIsDisplayed(MenuType.DAILY_DATA);
|
||||
Double dailyTotal = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.DAILY_TOTAL);
|
||||
long recordDate = readRecordDate();
|
||||
MenuDate date = (MenuDate) scripter.getCurrentMenu().getAttribute(MenuAttribute.DATE);
|
||||
Calendar instance = Calendar.getInstance();
|
||||
int year = date.getMonth() == 12 ? Calendar.getInstance().get(Calendar.YEAR) - 1 : Calendar.getInstance().get(Calendar.YEAR);
|
||||
instance.set(year, date.getMonth(), date.getDay());
|
||||
long recordDate = instance.getTimeInMillis();
|
||||
return new Tdd(recordDate, dailyTotal);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue