wip
This commit is contained in:
parent
e895ba65eb
commit
b47559647f
18 changed files with 364 additions and 185 deletions
|
@ -52,3 +52,18 @@ Testing:
|
|||
- Try to reproduce and open a ticket, add tag if any, otherwise add the hash of the commit used (right-click on the branch name select
|
||||
_Copy revision number_ or use _git show_ on the command-line) the branch name. Attach the log to the issue and label it as a bug.
|
||||
The logs can be found in _/storage/emulated/0/Android/data/info.nightscout.androidaps/_
|
||||
|
||||
v2 usage
|
||||
- When a BOLUS/TBR CANCELLED alert starts on the pump during bolusing or setting a TBR, this is caused by disconnect
|
||||
between pump and phone. The app will try to reconnect and confirm the alert and then retry the last action. Therefore,
|
||||
such an alarm shall be ignored (cancelling it is not a big issue, but will lead to the currently active action to
|
||||
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
|
||||
|
||||
Maybes:
|
||||
- reading/writing basal profiles to pump
|
||||
- splitted bolus/slower bolus delivery
|
||||
- extended bolus support
|
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import com.j256.ormlite.stmt.query.In;
|
||||
|
||||
/**
|
||||
* Created by mike on 07.06.2016.
|
||||
*/
|
||||
|
@ -24,7 +22,7 @@ public class Constants {
|
|||
public static final int hoursToKeepInDatabase = 72;
|
||||
public static final int daysToKeepHistoryInDatabase = 30;
|
||||
|
||||
public static final long keepAliveMsecs = 5 * 60 * 1000L;
|
||||
public static final long keepAliveMsecs = 60 * 1000L;
|
||||
|
||||
// SMS COMMUNICATOR
|
||||
public static final long remoteBolusMinDistance = 15 * 60 * 1000L;
|
||||
|
|
|
@ -30,7 +30,8 @@ import info.nightscout.utils.DecimalFormatter;
|
|||
public class ComboFragment extends SubscriberFragment implements View.OnClickListener {
|
||||
private static Logger log = LoggerFactory.getLogger(ComboFragment.class);
|
||||
|
||||
private TextView statusView;
|
||||
private TextView stateView;
|
||||
private TextView activityView;
|
||||
private TextView batteryView;
|
||||
private TextView reservoirView;
|
||||
private TextView lastConnectionView;
|
||||
|
@ -44,7 +45,8 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
|
|||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.combopump_fragment, container, false);
|
||||
|
||||
statusView = (TextView) view.findViewById(R.id.combo_status);
|
||||
stateView = (TextView) view.findViewById(R.id.combo_state);
|
||||
activityView = (TextView) view.findViewById(R.id.combo_activity);
|
||||
batteryView = (TextView) view.findViewById(R.id.combo_pumpstate_battery);
|
||||
reservoirView = (TextView) view.findViewById(R.id.combo_insulinstate);
|
||||
lastConnectionView = (TextView) view.findViewById(R.id.combo_lastconnection);
|
||||
|
@ -70,52 +72,48 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
|
|||
});
|
||||
thread.start();
|
||||
break;
|
||||
case R.id.combo_history:
|
||||
// TODO show popup with warnings/errors from the pump
|
||||
case R.id.combo_error_history:
|
||||
// TODO show popup with pump errors and comm problems
|
||||
break;
|
||||
case R.id.combo_stats:
|
||||
// TODO show TDD stats from the pump
|
||||
// TODO show TDD stats from the pump (later)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventComboPumpUpdateGUI ev) {
|
||||
if (ev.status != null) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
statusView.setText(ev.status);
|
||||
statusView.setTextColor(Color.WHITE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateGUI();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateGUI() {
|
||||
Activity activity = getActivity();
|
||||
final Activity activity = getActivity();
|
||||
log.debug("aCtI: activity available? " + (activity != null));
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ComboPlugin plugin = ComboPlugin.getPlugin();
|
||||
|
||||
// activity
|
||||
String activity = plugin.getPump().activity;
|
||||
activityView.setText(activity != null ? activity : "Idle");
|
||||
|
||||
if (plugin.isInitialized()) {
|
||||
// status
|
||||
statusView.setText(plugin.getPump().state.getStateSummary());
|
||||
if (plugin.getPump().state.errorMsg != null) {
|
||||
statusView.setTextColor(Color.RED);
|
||||
PumpState ps = plugin.getPump().state;
|
||||
stateView.setText(plugin.getPump().state.getStateSummary());
|
||||
if (plugin.getPump().state.errorMsg != null
|
||||
|| ps.insulinState == PumpState.EMPTY
|
||||
|| ps.batteryState == PumpState.EMPTY) {
|
||||
stateView.setTextColor(Color.RED);
|
||||
} else if (plugin.getPump().state.suspended) {
|
||||
statusView.setTextColor(Color.YELLOW);
|
||||
stateView.setTextColor(Color.YELLOW);
|
||||
} else {
|
||||
statusView.setTextColor(Color.WHITE);
|
||||
stateView.setTextColor(Color.WHITE);
|
||||
}
|
||||
|
||||
// battery
|
||||
PumpState ps = plugin.getPump().state;
|
||||
if (ps.batteryState == PumpState.EMPTY) {
|
||||
batteryView.setText("{fa-battery-empty}");
|
||||
batteryView.setTextColor(Color.RED);
|
||||
|
@ -143,15 +141,14 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis
|
|||
if (lastCmdResult != null) {
|
||||
String minAgo = DateUtil.minAgo(lastCmdResult.completionTime);
|
||||
String time = DateUtil.timeString(lastCmdResult.completionTime);
|
||||
// TODO must not be within if (lastCmdResult) so we can complain if NO command ever worked; also move from completionTime to new times
|
||||
// TODO check all access to completionTime. useful anymore?
|
||||
if (plugin.getPump().lastSuccessfulConnection < System.currentTimeMillis() + 30 * 60 * 1000) {
|
||||
lastConnectionView.setText(
|
||||
"No successful connection" +
|
||||
"\nwithin the last " + minAgo + " min");
|
||||
lastConnectionView.setText("No connection for " + minAgo + " min");
|
||||
lastConnectionView.setTextColor(Color.RED);
|
||||
}
|
||||
if (plugin.getPump().lastConnectionAttempt > plugin.getPump().lastSuccessfulConnection) {
|
||||
lastConnectionView.setText("" + minAgo + " (" + time + ")" +
|
||||
"\nLast connect attempt failed");
|
||||
lastConnectionView.setText("Last connect attempt failed");
|
||||
lastConnectionView.setTextColor(Color.YELLOW);
|
||||
} else {
|
||||
lastConnectionView.setText("" + minAgo + " (" + time + ")");
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.PumpCombo;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -22,7 +16,7 @@ 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.Error;
|
||||
import de.jotomo.ruffy.spi.history.PumpError;
|
||||
import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
|
||||
import de.jotomo.ruffy.spi.history.Tbr;
|
||||
import de.jotomo.ruffyscripter.RuffyCommandsV1Impl;
|
||||
|
@ -44,7 +38,6 @@ import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
|||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 05.08.2016.
|
||||
|
@ -205,23 +198,24 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
@NonNull
|
||||
@Override
|
||||
public Date lastDataTime() {
|
||||
CommandResult lastCmdResult = pump.lastCmdResult;
|
||||
return lastCmdResult != null ? new Date(lastCmdResult.completionTime) : new Date(0);
|
||||
return new Date(pump.lastSuccessfulConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void refreshDataFromPump(String reason) {
|
||||
log.debug("RefreshDataFromPump called");
|
||||
|
||||
if (pump.lastCmdResult == null) {
|
||||
initializePump();
|
||||
} else {
|
||||
boolean firstRun = pump.lastCmdResult == null;
|
||||
|
||||
runCommand("Refreshing", new CommandExecution() {
|
||||
@Override
|
||||
public CommandResult execute() {
|
||||
return ruffyScripter.readHistory(new PumpHistoryRequest().reservoirLevel(true).bolusHistory(PumpHistoryRequest.LAST));
|
||||
}
|
||||
});
|
||||
|
||||
if (firstRun) {
|
||||
initializePump();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,8 +579,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
|
||||
}
|
||||
|
||||
private CommandResult runCommand(String status, boolean checkTbrMisMatch, CommandExecution commandExecution) {
|
||||
MainApp.bus().post(new EventComboPumpUpdateGUI(status));
|
||||
private CommandResult runCommand(String activity, boolean checkTbrMisMatch, CommandExecution commandExecution) {
|
||||
pump.activity = activity;
|
||||
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||
|
||||
CommandResult commandResult = commandExecution.execute();
|
||||
|
||||
if (commandResult.success) {
|
||||
|
@ -606,17 +602,19 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
// get the current state, then decide what makes sense to do further, if anything,
|
||||
// send next request.
|
||||
// then request state again ... ?
|
||||
if (commandResult.state.errorMsg != null) {
|
||||
// TODO rethink this errorMsg field;
|
||||
|
||||
/* if (commandResult.state.errorMsg != null) {
|
||||
CommandResult takeOverAlarmResult = ruffyScripter.takeOverAlarms();
|
||||
|
||||
for (Error error : takeOverAlarmResult.history.errorHistory) {
|
||||
for (PumpError pumpError : takeOverAlarmResult.history.pumpErrorHistory) {
|
||||
MainApp.bus().post(new EventNewNotification(
|
||||
new Notification(Notification.COMBO_PUMP_ERROR,
|
||||
"Pump alarm: " + error.message, Notification.URGENT)));
|
||||
new Notification(Notification.COMBO_PUMP_ALARM,
|
||||
"Pump alarm: " + pumpError.message, Notification.URGENT)));
|
||||
}
|
||||
|
||||
commandResult.state = takeOverAlarmResult.state;
|
||||
}
|
||||
}*/
|
||||
|
||||
pump.lastCmdResult = commandResult;
|
||||
pump.state = commandResult.state;
|
||||
|
@ -632,20 +630,21 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
log.error("JOE: no!");
|
||||
} else {
|
||||
// still crashable ...
|
||||
// TODO only update if command was successful? -> KeepAliveReceiver, triggering alarm on unavaiblae pump
|
||||
pump.lastCmdResult.completionTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// TOOD
|
||||
// TODO merge all new history here?
|
||||
if (commandResult.history != null) {
|
||||
if (commandResult.history.reservoirLevel != -1) {
|
||||
pump.reservoirLevel = commandResult.history.reservoirLevel;
|
||||
}
|
||||
pump.history = commandResult.history;
|
||||
if (pump.history.bolusHistory.size() > 0) {
|
||||
pump.lastBolus = pump.history.bolusHistory.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO in the event of an error schedule a resync
|
||||
|
||||
pump.activity = null;
|
||||
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||
return commandResult;
|
||||
}
|
||||
|
|
|
@ -10,16 +10,17 @@ import de.jotomo.ruffy.spi.history.Bolus;
|
|||
import de.jotomo.ruffy.spi.history.PumpHistory;
|
||||
|
||||
class ComboPump {
|
||||
public long lastSuccessfulConnection;
|
||||
public long lastConnectionAttempt;
|
||||
|
||||
// TODO actually ... this isn't about successful command execution, but whether we could connect to the pump at all
|
||||
volatile long lastSuccessfulConnection;
|
||||
volatile long lastConnectionAttempt;
|
||||
@Nullable
|
||||
volatile CommandResult lastCmdResult;
|
||||
|
||||
public volatile String activity;
|
||||
@NonNull
|
||||
volatile PumpState state = new PumpState();
|
||||
@NonNull
|
||||
volatile PumpHistory history = new PumpHistory();
|
||||
@Nullable
|
||||
volatile Bolus lastBolus;
|
||||
volatile int reservoirLevel = -1;
|
||||
@NonNull
|
||||
|
||||
volatile PumpHistory history = new PumpHistory();
|
||||
}
|
||||
|
|
|
@ -5,11 +5,4 @@ package info.nightscout.androidaps.plugins.PumpCombo.events;
|
|||
*/
|
||||
|
||||
public class EventComboPumpUpdateGUI {
|
||||
public EventComboPumpUpdateGUI() {}
|
||||
|
||||
public EventComboPumpUpdateGUI(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String status;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ public class KeepAliveReceiver extends BroadcastReceiver {
|
|||
// fixing the problem takes longer (or is not immediately possible because the pump was forgotten)?
|
||||
// suppress this for another 25m if the message was dismissed?
|
||||
// The alarm sound is played back as regular media, that means it might be muted if sound level is at 0
|
||||
// a simple 'Enable/disable alarms' button on the actions tab?
|
||||
Notification n = new Notification(Notification.PUMP_UNREACHABLE, "Pump unreachable", Notification.URGENT);
|
||||
n.soundId = R.raw.alarm;
|
||||
MainApp.bus().post(new EventNewNotification(n));
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingRight="5dp"
|
||||
android:text="Status"
|
||||
android:text="State"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -43,14 +43,13 @@
|
|||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/combo_status"
|
||||
android:id="@+id/combo_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingLeft="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:text="Initializating"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -145,6 +144,51 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@color/listdelimiter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:gravity="end"
|
||||
android:paddingRight="5dp"
|
||||
android:text="Activity"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingEnd="2dp"
|
||||
android:paddingStart="2dp"
|
||||
android:text=":"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/combo_activity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:paddingLeft="5dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
|
@ -316,17 +360,6 @@
|
|||
android:paddingRight="0dp"
|
||||
android:text="@string/combo_refresh" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/combo_history"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/icon_danarhistory"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="@string/pump_history" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/combo_stats"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
|
@ -336,8 +369,20 @@
|
|||
android:drawableTop="@drawable/icon_danarstats"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:visibility="gone"
|
||||
android:text="@string/combo_stats" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/combo_error_history"
|
||||
style="@style/ButtonSmallFontStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="@drawable/icon_cp_aaps_offline"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="@string/pump_errors_history" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -269,7 +269,7 @@
|
|||
<string name="danarprofile_dia">DIA [h]</string>
|
||||
<string name="danarprofile_dia_summary">Duration of Insulin Activity</string>
|
||||
<string name="failedupdatebasalprofile">Failed to update basal profile</string>
|
||||
<string name="pump_history">History</string>
|
||||
<string name="pump_errors_history">Errors</string>
|
||||
<string name="danar_historyreload">Reload</string>
|
||||
<string name="uploading">Uploading</string>
|
||||
<string name="danar_ebolus">E bolus</string>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package de.jotomo.ruffy.spi;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/** State displayed on the main screen of the pump. */
|
||||
public class PumpState {
|
||||
public Date timestamp = new Date();
|
||||
public String menu = null;
|
||||
public boolean tbrActive = false;
|
||||
/** TBR percentage. 100% means no TBR active, just the normal basal rate running. */
|
||||
public int tbrPercent = -1;
|
||||
|
@ -30,6 +28,11 @@ public class PumpState {
|
|||
|
||||
public int activeBasalProfileNumber;
|
||||
|
||||
public PumpState menu(String menu) {
|
||||
this.menu = menu;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PumpState tbrActive(boolean tbrActive) {
|
||||
this.tbrActive = tbrActive;
|
||||
return this;
|
||||
|
@ -76,17 +79,19 @@ public class PumpState {
|
|||
}
|
||||
|
||||
public String getStateSummary() {
|
||||
if (errorMsg != null)
|
||||
return errorMsg;
|
||||
if (menu == null)
|
||||
return "Unreachable";
|
||||
else if (suspended && (batteryState == EMPTY || insulinState == EMPTY))
|
||||
return "Suspended due to error";
|
||||
else if (suspended)
|
||||
return "Suspended";
|
||||
return "Suspended by user";
|
||||
return "Running";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PumpState{" +
|
||||
"timestamp=" + timestamp +
|
||||
"menu=" + menu +
|
||||
", tbrActive=" + tbrActive +
|
||||
", tbrPercent=" + tbrPercent +
|
||||
", tbrRate=" + tbrRate +
|
||||
|
|
|
@ -13,14 +13,73 @@ public interface RuffyCommands {
|
|||
|
||||
CommandResult cancelTbr();
|
||||
|
||||
// TODO read Dana code wrt to syncing and such
|
||||
|
||||
/** Confirms an active alarm on the pump. The state returned is the state after the alarm
|
||||
* has been confirmed. Confirmed alerts are returned in history.errorHistory. */
|
||||
* has been confirmed. Confirmed alerts are returned in history.pumpErrorHistory. */
|
||||
@Deprecated
|
||||
// TODO rename to confirmActiveAlarm (single)
|
||||
// add a field activeAlarm to PumpState and put logic in ComboPlugin.
|
||||
CommandResult takeOverAlarms();
|
||||
// let this be an actual command in RS? or extend readPumpState wit ha flag to return confirmed errors?
|
||||
|
||||
/* plan:
|
||||
|
||||
let errors ring on the pump (all require interacting with the pump anyways and they
|
||||
should not be subject to errors in AAPS/ruffy.
|
||||
|
||||
When connecting to the pump, read the current state. If a warning(s) is ongoing
|
||||
confirm it and forward it and let AAPS display it.
|
||||
Check if a previous command failed (tbr/bolus) and if so, DON'T report a warning
|
||||
caused by an interrupted command.
|
||||
Put the logic in AAPS: don't have readPumpState automatically confirm anything,
|
||||
but read state, call takeOverAlarm(alarm)
|
||||
|
||||
concrete warnings???
|
||||
tbr cancelled => we can almost always just confirm this, we sync aaps if neded
|
||||
bolus => basically the same with SMBs, for user-initiated boluses and error should be reported
|
||||
properly, but that should work since it's interactive and PumpEneact result is
|
||||
or should be checked (verify it is)
|
||||
deliwerTreatment knows if it's SMB or not, whether it's okay to dismiss bolus cancelled alarm.
|
||||
|
||||
battery low => always forward (not configurable, whole point is to make AAPS master)
|
||||
cartridge low => always forward
|
||||
|
||||
when sync detects a significant mismatch it should alert?
|
||||
big bolus on pump aaps didn't knew about???
|
||||
removing a big bolus in aaps db since it's not in pump history? warn? aaps bug.
|
||||
|
||||
==> think this whole comm errors thing through (incl. auto/reconnect, auto-confirm
|
||||
), on LoD - 1 and go back to coding after that
|
||||
|
||||
open: dealing with low cartridge/battery during bolus.
|
||||
also: dealing with empty cartridge/battery alarms we let ring (force resync
|
||||
when 'next possible'. force resync when coming from a suspended state, or any
|
||||
error state in general.
|
||||
if cartridge is low, check reservoir before each bolus and don't attempt
|
||||
to bolus if not enough in reservoir for bolus?
|
||||
(testers: bolus with cartridge very low to run in such scenarios - forget the
|
||||
cartridge is low).
|
||||
|
||||
so: * confirm pump warnings; for tbr/bolus cancelled caused by connection loss don't
|
||||
report them to the user (on disconnect set a flag 'error caused by us' or use.
|
||||
also note connection lose and force history resync if appropriate(?) (LAST).
|
||||
* stuff low warnings: confirm, show in combo tab and give overview notification
|
||||
* keepaliver receiver raises an urgent error if there have been no pump comms in
|
||||
> 25m
|
||||
* errors always ring on the pump, are critical and require the pump to be interacted
|
||||
with, so they're not confirmed. if encountered, they're read and also reported as
|
||||
urgent on the phone. cancel again if we see the user has confirmed them on the pump?
|
||||
(parent monitoring, needing to see an error).
|
||||
make Combo->Status red and "Occlusion" for errors?
|
||||
*/
|
||||
|
||||
boolean isPumpAvailable();
|
||||
|
||||
boolean isPumpBusy();
|
||||
|
||||
// start everything with this: read pump state.
|
||||
// see if there's an error active.
|
||||
CommandResult readPumpState();
|
||||
|
||||
CommandResult readHistory(PumpHistoryRequest request);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package de.jotomo.ruffy.spi.history;
|
||||
|
||||
public class Error extends HistoryRecord {
|
||||
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;
|
||||
/** Error message, in the language configured on the pump. */
|
||||
public final String message;
|
||||
|
||||
public Error(long timestamp, String code, String message) {
|
||||
public PumpError(long timestamp, String code, String message) {
|
||||
super(timestamp);
|
||||
this.code = code;
|
||||
this.message = message;
|
|
@ -3,7 +3,6 @@ package de.jotomo.ruffy.spi.history;
|
|||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PumpHistory {
|
||||
|
@ -13,7 +12,7 @@ public class PumpHistory {
|
|||
@NonNull
|
||||
public List<Tbr> tbrHistory = new ArrayList<>();
|
||||
@NonNull
|
||||
public List<Error> errorHistory = new ArrayList<>();
|
||||
public List<PumpError> pumpErrorHistory = new ArrayList<>();
|
||||
@NonNull
|
||||
public List<Tdd> tddHistory = new ArrayList<>();
|
||||
|
||||
|
@ -33,8 +32,8 @@ public class PumpHistory {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PumpHistory errorHistory(List<Error> errorHistory) {
|
||||
this.errorHistory = errorHistory;
|
||||
public PumpHistory errorHistory(List<PumpError> pumpErrorHistory) {
|
||||
this.pumpErrorHistory = pumpErrorHistory;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -49,7 +48,7 @@ public class PumpHistory {
|
|||
"reservoirLevel=" + reservoirLevel +
|
||||
", bolusHistory=" + bolusHistory.size() +
|
||||
", tbrHistory=" + tbrHistory.size() +
|
||||
", errorHistory=" + errorHistory.size() +
|
||||
", pumpErrorHistory=" + pumpErrorHistory.size() +
|
||||
", tddHistory=" + tddHistory.size() +
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public class PumpHistoryRequest {
|
|||
|
||||
public long bolusHistory = SKIP;
|
||||
public long tbrHistory = SKIP;
|
||||
public long errorHistory = SKIP;
|
||||
public long pumpErrorHistory = SKIP;
|
||||
public long tddHistory = SKIP;
|
||||
|
||||
public PumpHistoryRequest reservoirLevel(boolean reservoirLevel) {
|
||||
|
@ -33,7 +33,7 @@ public class PumpHistoryRequest {
|
|||
}
|
||||
|
||||
public PumpHistoryRequest errorHistory(long errorHistory) {
|
||||
this.errorHistory = errorHistory;
|
||||
this.pumpErrorHistory = errorHistory;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class PumpHistoryRequest {
|
|||
"reservoirLevel=" + reservoirLevel +
|
||||
", bolusHistory=" + bolusHistory +
|
||||
", tbrHistory=" + tbrHistory +
|
||||
", errorHistory=" + errorHistory +
|
||||
", pumpErrorHistory=" + pumpErrorHistory +
|
||||
", tddHistory=" + tddHistory +
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import de.jotomo.ruffy.spi.BolusProgressReporter;
|
|||
import de.jotomo.ruffy.spi.CommandResult;
|
||||
import de.jotomo.ruffy.spi.PumpState;
|
||||
import de.jotomo.ruffy.spi.RuffyCommands;
|
||||
import de.jotomo.ruffy.spi.history.Error;
|
||||
import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
|
||||
import de.jotomo.ruffyscripter.commands.BolusCommand;
|
||||
import de.jotomo.ruffyscripter.commands.CancelTbrCommand;
|
||||
|
@ -40,6 +39,7 @@ import de.jotomo.ruffyscripter.commands.ReadHistoryCommand;
|
|||
import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand;
|
||||
import de.jotomo.ruffyscripter.commands.SetBasalProfileCommand;
|
||||
import de.jotomo.ruffyscripter.commands.SetTbrCommand;
|
||||
import de.jotomo.ruffyscripter.commands.TakeOverAlarmsCommand;
|
||||
|
||||
// TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully.
|
||||
// Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos
|
||||
|
@ -256,12 +256,12 @@ public class RuffyScripter implements RuffyCommands {
|
|||
return new CommandResult().message(Joiner.on("\n").join(violations)).state(readPumpStateInternal());
|
||||
}
|
||||
|
||||
// TODO simplify, hard to reason about exists
|
||||
synchronized (RuffyScripter.class) {
|
||||
try {
|
||||
activeCmd = cmd;
|
||||
long connectStart = System.currentTimeMillis();
|
||||
ensureConnected();
|
||||
final RuffyScripter scripter = this;
|
||||
final Returnable returnable = new Returnable();
|
||||
class CommandRunner {
|
||||
public void run() {
|
||||
|
@ -294,7 +294,7 @@ public class RuffyScripter implements RuffyCommands {
|
|||
PumpState pumpState = readPumpStateInternal();
|
||||
log.debug("Pump state before running command: " + pumpState);
|
||||
long cmdStartTime = System.currentTimeMillis();
|
||||
cmd.setScripter(scripter);
|
||||
cmd.setScripter(RuffyScripter.this);
|
||||
returnable.cmdResult = cmd.execute();
|
||||
long cmdEndTime = System.currentTimeMillis();
|
||||
returnable.cmdResult.completionTime = cmdEndTime;
|
||||
|
@ -333,6 +333,11 @@ public class RuffyScripter implements RuffyCommands {
|
|||
reconnect();
|
||||
// TODO at least for bigger boluses we should check history after reconnect to make sure
|
||||
// we haven't issued that bolus within the last 1-2m? in case there's a bug in the code ...
|
||||
|
||||
// TODO: only do the reconnect to confirm the alert, then return and let the ComboPlugin decide what to do next;
|
||||
// for bolus: how ... run 'step 2': checking/reading history?! step1 being bolus delivery, so have different resume points? ggrrrmpf
|
||||
// less logic in scripter; just reconnect to confirm alert if needed, then return with error;
|
||||
// let CP read history.LAST to see what actually happened and then resume appropriately.
|
||||
cmdThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -421,6 +426,11 @@ public class RuffyScripter implements RuffyCommands {
|
|||
ensureConnected();
|
||||
if (getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) {
|
||||
String errorMessage = (String) getCurrentMenu().getAttribute(MenuAttribute.MESSAGE);
|
||||
// TODO bolus cancelled is raised BEFORE a bolus is started. if disconnect occurs after
|
||||
// bolus has started (or the user interacts with the pump, the bolus continues.
|
||||
// in that case, reconnecting and restarting the command lets to a DUPLICATE bolus.
|
||||
// add a method restartAllowed(), which accesses a flag bolusDelivering started, which
|
||||
// is set false then?
|
||||
if (activeCmd.getReconnectAlarm() != null && activeCmd.getReconnectAlarm().equals(errorMessage)) {
|
||||
log.debug("Confirming alert caused by disconnect: " + errorMessage);
|
||||
// confirm alert
|
||||
|
@ -454,6 +464,7 @@ public class RuffyScripter implements RuffyCommands {
|
|||
return false;
|
||||
}
|
||||
|
||||
// aren't at main_menu after alert anyways? unless bolus i still going (also main_menu); low cartridge on bolus needs to be handled specially, by bolus command
|
||||
returnToRootMenu();
|
||||
|
||||
return getCurrentMenu().getType() == MenuType.MAIN_MENU;
|
||||
|
@ -530,9 +541,12 @@ public class RuffyScripter implements RuffyCommands {
|
|||
PumpState state = new PumpState();
|
||||
Menu menu = currentMenu;
|
||||
if (menu == null) {
|
||||
return new PumpState().errorMsg("Menu is not available");
|
||||
return state;
|
||||
}
|
||||
|
||||
MenuType menuType = menu.getType();
|
||||
state.menu = menuType.name();
|
||||
|
||||
if (menuType == MenuType.MAIN_MENU) {
|
||||
Double tbrPercentage = (Double) menu.getAttribute(MenuAttribute.TBR);
|
||||
if (tbrPercentage != 100) {
|
||||
|
@ -545,10 +559,6 @@ public class RuffyScripter implements RuffyCommands {
|
|||
}
|
||||
state.batteryState = ((int) menu.getAttribute(MenuAttribute.BATTERY_STATE));
|
||||
state.insulinState = ((int) menu.getAttribute(MenuAttribute.INSULIN_STATE));
|
||||
// TODO v2, read current base basal rate, which is shown center when no TBR is active.
|
||||
// Check if that holds true when an extended bolus is running.
|
||||
// Add a field to PumpStatus, rather than renaming/overloading tbrRate to mean
|
||||
// either TBR rate or basal rate depending on whether a TBR is active.
|
||||
} else if (menuType == MenuType.WARNING_OR_ERROR) {
|
||||
state.errorMsg = (String) menu.getAttribute(MenuAttribute.MESSAGE);
|
||||
} else if (menuType == MenuType.STOP) {
|
||||
|
@ -556,14 +566,7 @@ public class RuffyScripter implements RuffyCommands {
|
|||
state.batteryState = ((int) menu.getAttribute(MenuAttribute.BATTERY_STATE));
|
||||
state.insulinState = ((int) menu.getAttribute(MenuAttribute.INSULIN_STATE));
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (MenuAttribute menuAttribute : menu.attributes()) {
|
||||
sb.append(menuAttribute);
|
||||
sb.append(": ");
|
||||
sb.append(menu.getAttribute(menuAttribute));
|
||||
sb.append("\n");
|
||||
}
|
||||
state.errorMsg = "Pump is on menu " + menuType + ", listing attributes: \n" + sb.toString();
|
||||
// just return the PumpState with the menu set
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
@ -619,6 +622,7 @@ public class RuffyScripter implements RuffyCommands {
|
|||
// TODO this is probably due to a disconnect and rtDisconnect having nulled currentMenu.
|
||||
// This here might just work, but needs a more controlled approach when implementing
|
||||
// something to deal with connection loses
|
||||
// TODO force reconnect? and retry?
|
||||
while (currentMenu == null) {
|
||||
if (System.currentTimeMillis() > timeout) {
|
||||
throw new CommandException().message("Unable to read current menu");
|
||||
|
@ -630,14 +634,9 @@ public class RuffyScripter implements RuffyCommands {
|
|||
}
|
||||
|
||||
public void pressUpKey() {
|
||||
// wrapNoNotTheSubwayKind(new Step() {
|
||||
// @Override
|
||||
// public void doStep() {
|
||||
log.debug("Pressing up key");
|
||||
pressKey(Key.UP);
|
||||
log.debug("Releasing up key");
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
public void pressDownKey() {
|
||||
|
@ -742,7 +741,7 @@ public class RuffyScripter implements RuffyCommands {
|
|||
waitForMenuUpdate(60, "Timeout waiting for menu update");
|
||||
}
|
||||
|
||||
public void waitForMenuUpdate(long timeoutInSeconds, String errorMessage) {
|
||||
private void waitForMenuUpdate(long timeoutInSeconds, String errorMessage) {
|
||||
long timeoutExpired = System.currentTimeMillis() + timeoutInSeconds * 1000;
|
||||
long initialUpdateTime = menuLastUpdated;
|
||||
while (initialUpdateTime == menuLastUpdated) {
|
||||
|
@ -869,32 +868,7 @@ public class RuffyScripter implements RuffyCommands {
|
|||
|
||||
@Override
|
||||
public CommandResult takeOverAlarms() {
|
||||
if (getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR) {
|
||||
return new CommandResult().success(false).enacted(false).message("No alarm active on the pump");
|
||||
}
|
||||
while (currentMenu.getType() == MenuType.WARNING_OR_ERROR) {
|
||||
new Error(System.currentTimeMillis(),
|
||||
"",
|
||||
// TODO
|
||||
// codes unqiue across W/E?
|
||||
// (int) currentMenu.getAttribute(MenuAttribute.WARNING),
|
||||
// (int) currentMenu.getAttribute(MenuAttribute.ERROR),
|
||||
(String) currentMenu.getAttribute(MenuAttribute.MESSAGE));
|
||||
}
|
||||
// confirm alert
|
||||
verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR);
|
||||
pressCheckKey();
|
||||
// dismiss alert
|
||||
verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR);
|
||||
pressCheckKey();
|
||||
waitForMenuToBeLeft(MenuType.WARNING_OR_ERROR);
|
||||
|
||||
PumpState pumpState = readPumpStateInternal();
|
||||
return new CommandResult()
|
||||
.success(true)
|
||||
.enacted(false /* well, no treatments were enacted ... */)
|
||||
.message(pumpState.errorMsg) // todo yikes?
|
||||
.state(pumpState);
|
||||
return runCommand(new TakeOverAlarmsCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,6 +26,11 @@ public class BolusCommand extends BaseCommand {
|
|||
private final BolusProgressReporter bolusProgressReporter;
|
||||
private volatile boolean cancelRequested;
|
||||
|
||||
// TODO make CommandResult a field that is updated as the command progress so that we can
|
||||
// (also) see via cmdResult.enacted if something has been enacted and how safe it is to
|
||||
// restart the command (also checking history of course, but lets double check this cruical
|
||||
// part)
|
||||
|
||||
public BolusCommand(double bolus, BolusProgressReporter bolusProgressReporter) {
|
||||
this.bolus = bolus;
|
||||
this.bolusProgressReporter = bolusProgressReporter;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package de.jotomo.ruffyscripter.commands;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute;
|
||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
|
||||
import org.monkey.d.ruffy.ruffy.driver.display.menu.BolusType;
|
||||
|
@ -30,50 +32,38 @@ public class ReadHistoryCommand extends BaseCommand {
|
|||
}
|
||||
if (request.bolusHistory != PumpHistoryRequest.SKIP
|
||||
|| request.tbrHistory != PumpHistoryRequest.SKIP
|
||||
|| request.errorHistory != PumpHistoryRequest.SKIP
|
||||
|| request.pumpErrorHistory != PumpHistoryRequest.SKIP
|
||||
|| request.tddHistory != PumpHistoryRequest.SKIP) {
|
||||
scripter.navigateToMenu(MenuType.MY_DATA_MENU);
|
||||
scripter.verifyMenuIsDisplayed(MenuType.MY_DATA_MENU);
|
||||
scripter.pressCheckKey();
|
||||
|
||||
// bolus history
|
||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_DATA);
|
||||
if (request.bolusHistory != PumpHistoryRequest.SKIP) {
|
||||
int totalRecords = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.TOTAL_RECORD);
|
||||
if (totalRecords > 0) {
|
||||
if (request.bolusHistory == PumpHistoryRequest.LAST) {
|
||||
// Could also be extended, multiwave:
|
||||
BolusType bolusType = (BolusType) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_TYPE);
|
||||
if (!bolusType.equals(BolusType.NORMAL)) {
|
||||
throw new CommandException().success(false).enacted(false).message("Unsupported bolus type encountered: " + bolusType);
|
||||
Bolus bolus = readBolusRecord();
|
||||
history.bolusHistory.add(bolus);
|
||||
} else {
|
||||
readBolusRecords(request.bolusHistory);
|
||||
}
|
||||
}
|
||||
Double bolus = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS);
|
||||
MenuDate date = (MenuDate) scripter.getCurrentMenu().getAttribute(MenuAttribute.DATE);
|
||||
MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME);
|
||||
// TODO handle year changes; if current month == 1 and record date == 12, use $YEAR-1
|
||||
int currentMonth = new Date().getMonth() + 1;
|
||||
int currentYear = new Date().getYear() + 1900;
|
||||
if (currentMonth == 1 && date.getMonth() == 12) {
|
||||
currentYear -= 1;
|
||||
}
|
||||
long recordDate = new Date(currentYear - 1900, date.getMonth() - 1, date.getDay(), time.getHour(), time.getMinute()).getTime();
|
||||
history.bolusHistory.add(new Bolus(recordDate, bolus));
|
||||
|
||||
// int record = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD);
|
||||
// int totalRecords = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.TOTAL_RECORD);
|
||||
|
||||
/*
|
||||
read displayed date, bolus, add to history
|
||||
while data > last known, press up to go through history
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
// error history
|
||||
scripter.pressMenuKey();
|
||||
scripter.verifyMenuIsDisplayed(MenuType.ERROR_DATA);
|
||||
if (request.errorHistory != PumpHistoryRequest.SKIP) {
|
||||
if (request.pumpErrorHistory != PumpHistoryRequest.SKIP) {
|
||||
int code = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.WARNING);
|
||||
String message = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE);
|
||||
MenuDate date = (MenuDate) scripter.getCurrentMenu().getAttribute(MenuAttribute.DATE);
|
||||
MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME);
|
||||
|
||||
}
|
||||
|
||||
// tdd history
|
||||
scripter.pressMenuKey();
|
||||
scripter.verifyMenuIsDisplayed(MenuType.DAILY_DATA);
|
||||
if (request.tddHistory != PumpHistoryRequest.SKIP) {
|
||||
|
@ -81,6 +71,8 @@ public class ReadHistoryCommand extends BaseCommand {
|
|||
MenuDate date = (MenuDate) scripter.getCurrentMenu().getAttribute(MenuAttribute.DATE);
|
||||
MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME);
|
||||
}
|
||||
|
||||
// tbr history
|
||||
scripter.pressMenuKey();
|
||||
scripter.verifyMenuIsDisplayed(MenuType.TBR_DATA);
|
||||
if (request.tbrHistory != PumpHistoryRequest.SKIP) {
|
||||
|
@ -90,13 +82,50 @@ public class ReadHistoryCommand extends BaseCommand {
|
|||
// TODO start or end time?
|
||||
MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME);
|
||||
}
|
||||
|
||||
scripter.pressBackKey();
|
||||
scripter.returnToRootMenu();
|
||||
}
|
||||
scripter.verifyRootMenuIsDisplayed();
|
||||
}
|
||||
|
||||
return new CommandResult().success(true).enacted(false).history(history);
|
||||
}
|
||||
|
||||
private void readBolusRecords(long requestedTime) {
|
||||
int record = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD);
|
||||
int totalRecords = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.TOTAL_RECORD);
|
||||
while (record <= totalRecords) {
|
||||
Bolus bolus = readBolusRecord();
|
||||
if (requestedTime != PumpHistoryRequest.FULL && bolus.timestamp < requestedTime) {
|
||||
break;
|
||||
}
|
||||
history.bolusHistory.add(bolus);
|
||||
record = (int) scripter.getCurrentMenu().getAttribute(MenuAttribute.CURRENT_RECORD);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Bolus readBolusRecord() {
|
||||
// Could also be extended, multiwave
|
||||
BolusType bolusType = (BolusType) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_TYPE);
|
||||
if (!bolusType.equals(BolusType.NORMAL)) {
|
||||
throw new CommandException().success(false).enacted(false).message("Unsupported bolus type encountered: " + bolusType);
|
||||
}
|
||||
// TODO no bolus etc yet? How would that ever look?
|
||||
Double bolus = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS);
|
||||
MenuDate date = (MenuDate) scripter.getCurrentMenu().getAttribute(MenuAttribute.DATE);
|
||||
MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME);
|
||||
|
||||
// TODO handle year changes; if current month == 1 and record date == 12, use $YEAR-1
|
||||
int currentMonth = new Date().getMonth() + 1;
|
||||
int currentYear = new Date().getYear() + 1900;
|
||||
if (currentMonth == 1 && date.getMonth() == 12) {
|
||||
currentYear -= 1;
|
||||
}
|
||||
long recordDate = new Date(currentYear - 1900, date.getMonth() - 1, date.getDay(), time.getHour(), time.getMinute()).getTime();
|
||||
return new Bolus(recordDate, bolus);
|
||||
}
|
||||
|
||||
private void readReservoirLevel() {
|
||||
scripter.verifyRootMenuIsDisplayed();
|
||||
scripter.pressCheckKey();
|
||||
|
@ -112,4 +141,13 @@ public class ReadHistoryCommand extends BaseCommand {
|
|||
public List<String> validateArguments() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReadHistoryCommand{" +
|
||||
"request=" + request +
|
||||
", history=" + history +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package de.jotomo.ruffyscripter.commands;
|
||||
|
||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute;
|
||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import de.jotomo.ruffy.spi.CommandResult;
|
||||
import de.jotomo.ruffy.spi.PumpState;
|
||||
import de.jotomo.ruffy.spi.history.PumpError;
|
||||
|
||||
// TODO rename to ConfirmALarm(alarm) => logic in CP, just report back alarm, then explicitely confirm that one alarm.
|
||||
// multiple alarms oncy occur for errors (battery/cartdige low/occlusion) => let ring.
|
||||
public class TakeOverAlarmsCommand extends BaseCommand {
|
||||
@Override
|
||||
public CommandResult execute() {
|
||||
if (scripter.getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR) {
|
||||
return new CommandResult().success(false).enacted(false).message("No alarm active on the pump");
|
||||
}
|
||||
while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) {
|
||||
new PumpError(System.currentTimeMillis(),
|
||||
"",
|
||||
// TODO
|
||||
// codes unqiue across W/E?
|
||||
// (int) currentMenu.getAttribute(MenuAttribute.WARNING),
|
||||
// (int) currentMenu.getAttribute(MenuAttribute.ERROR),
|
||||
(String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE));
|
||||
}
|
||||
// confirm alert
|
||||
scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR);
|
||||
scripter.pressCheckKey();
|
||||
// dismiss alert
|
||||
scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR);
|
||||
scripter.pressCheckKey();
|
||||
scripter.waitForMenuToBeLeft(MenuType.WARNING_OR_ERROR);
|
||||
|
||||
PumpState pumpState = scripter.readPumpStateInternal();
|
||||
return new CommandResult()
|
||||
.success(true)
|
||||
.enacted(false /* well, no treatments were enacted ... */)
|
||||
// .message(pumpState.errorMsg) // todo yikes?
|
||||
.state(pumpState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validateArguments() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue