open loop mode & notification

This commit is contained in:
Milos Kozak 2016-06-26 11:43:26 +02:00
parent ff5043e99b
commit 2f16c9b998
17 changed files with 296 additions and 98 deletions

View file

@ -25,5 +25,5 @@ public class Config {
// Developing mode only - never turn on // Developing mode only - never turn on
// TODO: remove fakeGlucoseData // TODO: remove fakeGlucoseData
public static final boolean fakeGlucoseData = false; public static final boolean fakeGlucoseData = true;
} }

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps; package info.nightscout.androidaps;
import com.j256.ormlite.stmt.query.In;
/** /**
* Created by mike on 07.06.2016. * Created by mike on 07.06.2016.
*/ */
@ -13,5 +15,7 @@ public class Constants {
public static final double basalAbsoluteOnlyForCheckLimit = 10101010d; public static final double basalAbsoluteOnlyForCheckLimit = 10101010d;
public static final Integer basalPercentOnlyForCheckLimit = 10101010; public static final Integer basalPercentOnlyForCheckLimit = 10101010;
public static final Integer notificationID = 556677;
public static final int hoursToKeepInDatabase = 24; public static final int hoursToKeepInDatabase = 24;
} }

View file

@ -27,6 +27,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
public void onCreate(final Bundle savedInstanceState) { public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_treatments); addPreferencesFromResource(R.xml.pref_treatments);
if (Config.APS)
addPreferencesFromResource(R.xml.pref_closedmode);
if (Config.OPENAPSMAENABLED) if (Config.OPENAPSMAENABLED)
addPreferencesFromResource(R.xml.pref_openapsma); addPreferencesFromResource(R.xml.pref_openapsma);
if (Config.LOWSUSPEDENABLED) if (Config.LOWSUSPEDENABLED)

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 25.06.2016.
*/
public class EventRefreshOpenLoop {
}

View file

@ -7,8 +7,7 @@ import info.nightscout.androidaps.plugins.APSResult;
*/ */
public interface ConstraintsInterface { public interface ConstraintsInterface {
boolean isAutomaticProcessingEnabled(); boolean isClosedModeEnabled();
boolean manualConfirmationNeeded();
APSResult applyBasalConstraints(APSResult request); APSResult applyBasalConstraints(APSResult request);
Double applyBasalConstraints(Double absoluteRate); Double applyBasalConstraints(Double absoluteRate);
Integer applyBasalConstraints(Integer percentRate); Integer applyBasalConstraints(Integer percentRate);

View file

@ -709,27 +709,14 @@ public class ConfigBuilderFragment extends Fragment implements PluginBase, PumpI
* Constraints interface * Constraints interface
**/ **/
@Override @Override
public boolean isAutomaticProcessingEnabled() { public boolean isClosedModeEnabled() {
boolean result = true; boolean result = true;
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS); ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) { for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p; ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue; if (!p.isEnabled()) continue;
result = result && constrain.isAutomaticProcessingEnabled(); result = result && constrain.isClosedModeEnabled();
}
return result;
}
@Override
public boolean manualConfirmationNeeded() {
boolean result = false;
ArrayList<PluginBase> constraintsPlugins = MainActivity.getSpecificPluginsList(PluginBase.CONSTRAINTS);
for (PluginBase p : constraintsPlugins) {
ConstraintsInterface constrain = (ConstraintsInterface) p;
if (!p.isEnabled()) continue;
result = result || constrain.manualConfirmationNeeded();
} }
return result; return result;
} }

View file

@ -2,10 +2,17 @@ package info.nightscout.androidaps.plugins.Loop;
import android.app.Activity; import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v7.app.NotificationCompat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -20,11 +27,13 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventRefreshOpenLoop;
import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
@ -43,8 +52,6 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
TextView constraintsProcessedView; TextView constraintsProcessedView;
TextView setByPumpView; TextView setByPumpView;
boolean confirmed;
public class LastRun implements Parcelable { public class LastRun implements Parcelable {
public APSResult request = null; public APSResult request = null;
public APSResult constraintsProcessed = null; public APSResult constraintsProcessed = null;
@ -52,6 +59,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
public String source = null; public String source = null;
public Date lastAPSRun = null; public Date lastAPSRun = null;
public Date lastEnact = null; public Date lastEnact = null;
public Date lastOpenModeAccept = null;
@Override @Override
public int describeContents() { public int describeContents() {
@ -65,7 +73,8 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
dest.writeParcelable(setByPump, 0); dest.writeParcelable(setByPump, 0);
dest.writeString(source); dest.writeString(source);
dest.writeLong(lastAPSRun.getTime()); dest.writeLong(lastAPSRun.getTime());
dest.writeLong(lastEnact!= null ? lastEnact.getTime(): 0l); dest.writeLong(lastEnact != null ? lastEnact.getTime() : 0l);
dest.writeLong(lastOpenModeAccept != null ? lastOpenModeAccept.getTime() : 0l);
} }
public final Parcelable.Creator<LastRun> CREATOR = new Parcelable.Creator<LastRun>() { public final Parcelable.Creator<LastRun> CREATOR = new Parcelable.Creator<LastRun>() {
@ -85,6 +94,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
source = in.readString(); source = in.readString();
lastAPSRun = new Date(in.readLong()); lastAPSRun = new Date(in.readLong());
lastEnact = new Date(in.readLong()); lastEnact = new Date(in.readLong());
lastOpenModeAccept = new Date(in.readLong());
} }
public LastRun() { public LastRun() {
@ -186,7 +196,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
public void onClick(View view) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.loop_run: case R.id.loop_run:
invoke(); invoke(true);
break; break;
} }
@ -195,22 +205,15 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
@Subscribe @Subscribe
public void onStatusEvent(final EventTreatmentChange ev) { public void onStatusEvent(final EventTreatmentChange ev) {
ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder(); ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder();
if (constraintsInterface.isAutomaticProcessingEnabled()) { invoke(true);
invoke();
updateGUI();
}
} }
@Subscribe @Subscribe
public void onStatusEvent(final EventNewBG ev) { public void onStatusEvent(final EventNewBG ev) {
ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder(); invoke(true);
if (constraintsInterface.isAutomaticProcessingEnabled()) {
invoke();
updateGUI();
}
} }
private void invoke() { public void invoke(boolean allowNotification) {
ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder(); ConstraintsInterface constraintsInterface = MainApp.getConfigBuilder();
PumpInterface pumpInterface = MainApp.getConfigBuilder().getActivePump(); PumpInterface pumpInterface = MainApp.getConfigBuilder().getActivePump();
APSResult result = null; APSResult result = null;
@ -247,39 +250,63 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
return; return;
} }
confirmed = false;
if (constraintsInterface.manualConfirmationNeeded()) {
// TODO: user notification here
confirmed = true;
} else {
confirmed = true;
}
// check rate for constrais // check rate for constrais
APSResult resultAfterConstraints = result.clone(); APSResult resultAfterConstraints = result.clone();
constraintsInterface.applyBasalConstraints(resultAfterConstraints);
if (result.changeRequested) { if (lastRun == null) lastRun = new LastRun();
constraintsInterface.applyBasalConstraints(resultAfterConstraints); lastRun.request = result;
PumpEnactResult applyResult = pumpInterface.applyAPSRequest(resultAfterConstraints); lastRun.constraintsProcessed = resultAfterConstraints;
Date lastEnact = lastRun != null ? lastRun.lastEnact : new Date(0, 0, 0); lastRun.lastAPSRun = new Date();
lastRun = new LastRun(); lastRun.source = usedAPS != null ? ((PluginBase) usedAPS).getName() : "";
lastRun.request = result; lastRun.setByPump = null;
lastRun.constraintsProcessed = resultAfterConstraints;
lastRun.setByPump = applyResult; if (constraintsInterface.isClosedModeEnabled()) {
lastRun.source = ((PluginBase) usedAPS).getName(); if (result.changeRequested) {
lastRun.lastAPSRun = new Date(); PumpEnactResult applyResult = pumpInterface.applyAPSRequest(resultAfterConstraints);
if (applyResult.enacted) if (applyResult.enacted) {
lastRun.lastEnact = lastRun.lastAPSRun; lastRun.setByPump = applyResult;
else lastRun.lastEnact = lastRun.lastAPSRun;
lastRun.lastEnact = lastEnact; }
} else {
lastRun.setByPump = null;
lastRun.source = null;
}
} else { } else {
if (lastRun == null) lastRun = new LastRun(); if (result.changeRequested && allowNotification) {
lastRun.request = result; NotificationCompat.Builder builder =
lastRun.constraintsProcessed = resultAfterConstraints; new NotificationCompat.Builder(MainApp.instance().getApplicationContext());
lastRun.setByPump = null; builder.setSmallIcon(R.drawable.notification_icon)
lastRun.source = null; .setContentTitle(MainApp.resources.getString(R.string.openloop_newsuggestion))
lastRun.lastAPSRun = new Date(); .setContentText(resultAfterConstraints.toString())
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_ALARM)
.setVisibility(Notification.VISIBILITY_PUBLIC);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(MainApp.instance().getApplicationContext());
stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
NotificationManager mNotificationManager =
(NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(Constants.notificationID, builder.build());
MainApp.bus().post(new EventRefreshOpenLoop());
}
} }
updateGUI(); updateGUI();
MainApp.getConfigBuilder().uploadDeviceStatus(); MainApp.getConfigBuilder().uploadDeviceStatus();
} }
@ -296,7 +323,7 @@ public class LoopFragment extends Fragment implements View.OnClickListener, Plug
setByPumpView.setText(lastRun.setByPump != null ? lastRun.setByPump.toString() : ""); setByPumpView.setText(lastRun.setByPump != null ? lastRun.setByPump.toString() : "");
sourceView.setText(lastRun.source != null ? lastRun.source.toString() : ""); sourceView.setText(lastRun.source != null ? lastRun.source.toString() : "");
lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : ""); lastRunView.setText(lastRun.lastAPSRun != null && lastRun.lastAPSRun.getTime() != 0 ? lastRun.lastAPSRun.toLocaleString() : "");
lastEnactView.setText(lastRun.lastEnact!= null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : ""); lastEnactView.setText(lastRun.lastEnact != null && lastRun.lastEnact.getTime() != 0 ? lastRun.lastEnact.toLocaleString() : "");
} }
} }
}); });

View file

@ -317,17 +317,11 @@ public class ObjectivesFragment extends Fragment implements View.OnClickListener
* Constraints interface * Constraints interface
**/ **/
@Override @Override
public boolean isAutomaticProcessingEnabled() { public boolean isClosedModeEnabled() {
return true; // TODO: revert back return true; // TODO: revert back
//return objectives.get(3).started.getTime() > 0; //return objectives.get(3).started.getTime() > 0;
} }
@Override
public boolean manualConfirmationNeeded() {
return false; // TODO: revert back
//return objectives.get(3).started.getTime() < 0;
}
@Override @Override
public APSResult applyBasalConstraints(APSResult result) { public APSResult applyBasalConstraints(APSResult result) {
return result; return result;

View file

@ -171,9 +171,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener {
// Set BG if not old // Set BG if not old
BgReading lastBg = MainApp.getDbHelper().lastBg(); BgReading lastBg = MainApp.getDbHelper().lastBg();
Double lastBgValue = lastBg.valueToUnits(units);
if (lastBg != null) { if (lastBg != null) {
Double lastBgValue = lastBg.valueToUnits(units);
Double sens = profile.getIsf(NSProfile.secondsFromMidnight()); Double sens = profile.getIsf(NSProfile.secondsFromMidnight());
Double targetBGLow = profile.getTargetLow(NSProfile.secondsFromMidnight()); Double targetBGLow = profile.getTargetLow(NSProfile.secondsFromMidnight());
Double targetBGHigh = profile.getTargetHigh(NSProfile.secondsFromMidnight()); Double targetBGHigh = profile.getTargetHigh(NSProfile.secondsFromMidnight());

View file

@ -1,14 +1,15 @@
package info.nightscout.androidaps.plugins.Overview; package info.nightscout.androidaps.plugins.Overview;
import android.app.Activity; import android.app.Activity;
import android.content.DialogInterface;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.DashPathEffect; import android.graphics.DashPathEffect;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -34,18 +35,23 @@ import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainActivity;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.db.TempBasal; import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.events.EventRefreshOpenLoop;
import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Loop.LoopFragment;
import info.nightscout.androidaps.plugins.OpenAPSMA.IobTotal; import info.nightscout.androidaps.plugins.OpenAPSMA.IobTotal;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewExtendedBolusDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewExtendedBolusDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTempBasalDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTempBasalDialog;
@ -63,15 +69,18 @@ public class OverviewFragment extends Fragment implements PluginBase {
TextView deltaView; TextView deltaView;
TextView runningTempView; TextView runningTempView;
TextView iobView; TextView iobView;
TextView apsModeView;
GraphView bgGraph; GraphView bgGraph;
LinearLayout cancelTempLayout; LinearLayout cancelTempLayout;
LinearLayout setTempLayout; LinearLayout setTempLayout;
LinearLayout acceptTempLayout;
Button cancelTempButton; Button cancelTempButton;
Button treatmentButton; Button treatmentButton;
Button wizardButton; Button wizardButton;
Button setTempButton; Button setTempButton;
Button setExtenedButton; Button setExtenedButton;
Button acceptTempButton;
boolean visibleNow = false; boolean visibleNow = false;
Handler loopHandler = new Handler(); Handler loopHandler = new Handler();
@ -155,6 +164,7 @@ public class OverviewFragment extends Fragment implements PluginBase {
deltaView = (TextView) view.findViewById(R.id.overview_delta); deltaView = (TextView) view.findViewById(R.id.overview_delta);
runningTempView = (TextView) view.findViewById(R.id.overview_runningtemp); runningTempView = (TextView) view.findViewById(R.id.overview_runningtemp);
iobView = (TextView) view.findViewById(R.id.overview_iob); iobView = (TextView) view.findViewById(R.id.overview_iob);
apsModeView = (TextView) view.findViewById(R.id.overview_apsmode);
bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph); bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph);
cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp); cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp);
treatmentButton = (Button) view.findViewById(R.id.overview_treatment); treatmentButton = (Button) view.findViewById(R.id.overview_treatment);
@ -164,6 +174,8 @@ public class OverviewFragment extends Fragment implements PluginBase {
cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp); cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp);
setTempLayout = (LinearLayout) view.findViewById(R.id.overview_settemplayout); setTempLayout = (LinearLayout) view.findViewById(R.id.overview_settemplayout);
cancelTempLayout = (LinearLayout) view.findViewById(R.id.overview_canceltemplayout); cancelTempLayout = (LinearLayout) view.findViewById(R.id.overview_canceltemplayout);
acceptTempButton = (Button) view.findViewById(R.id.overview_accepttempbutton);
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
treatmentButton.setOnClickListener(new View.OnClickListener() { treatmentButton.setOnClickListener(new View.OnClickListener() {
@Override @Override
@ -212,6 +224,34 @@ public class OverviewFragment extends Fragment implements PluginBase {
} }
}); });
acceptTempButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MainApp.getConfigBuilder().getActiveLoop().invoke(false);
final LoopFragment.LastRun finalLastRun = MainApp.getConfigBuilder().getActiveLoop().lastRun;
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.changeRequested) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(getContext().getString(R.string.dialog));
builder.setMessage(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
PumpEnactResult applyResult = MainApp.getConfigBuilder().getActivePump().applyAPSRequest(finalLastRun.constraintsProcessed);
if (applyResult.enacted) {
finalLastRun.setByPump = applyResult;
finalLastRun.lastEnact = new Date();
finalLastRun.lastOpenModeAccept = new Date();
MainApp.getConfigBuilder().uploadDeviceStatus();
}
updateGUI();
}
});
builder.setNegativeButton(getContext().getString(R.string.cancel), null);
builder.show();
}
updateGUI();
}
});
updateGUI(); updateGUI();
return view; return view;
} }
@ -225,6 +265,34 @@ public class OverviewFragment extends Fragment implements PluginBase {
MainApp.bus().register(this); MainApp.bus().register(this);
} }
@Subscribe
public void onStatusEvent(final EventPreferenceChange ev) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updateGUI();
}
});
else
log.debug("EventPreferenceChange: Activity is null");
}
@Subscribe
public void onStatusEvent(final EventRefreshGui ev) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updateGUI();
}
});
else
log.debug("EventRefreshGui: Activity is null");
}
@Subscribe @Subscribe
public void onStatusEvent(final EventTreatmentChange ev) { public void onStatusEvent(final EventTreatmentChange ev) {
Activity activity = getActivity(); Activity activity = getActivity();
@ -267,6 +335,20 @@ public class OverviewFragment extends Fragment implements PluginBase {
log.debug("EventNewBG: Activity is null"); log.debug("EventNewBG: Activity is null");
} }
@Subscribe
public void onStatusEvent(final EventRefreshOpenLoop ev) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updateGUI();
}
});
else
log.debug("EventNewBG: Activity is null");
}
@Override @Override
public void setUserVisibleHint(boolean isVisibleToUser) { public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser); super.setUserVisibleHint(isVisibleToUser);
@ -295,6 +377,30 @@ public class OverviewFragment extends Fragment implements PluginBase {
if (bgGraph == null) if (bgGraph == null)
return; return;
// open loop mode
final LoopFragment.LastRun finalLastRun = MainApp.getConfigBuilder().getActiveLoop().lastRun;
if (Config.APS) {
apsModeView.setVisibility(View.VISIBLE);
if (MainApp.getConfigBuilder().isClosedModeEnabled())
apsModeView.setText(MainApp.resources.getString(R.string.closedloop));
else apsModeView.setText(MainApp.resources.getString(R.string.openloop));
} else {
apsModeView.setVisibility(View.GONE);
}
boolean showAcceptButton = true;
showAcceptButton = showAcceptButton && !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested
if (showAcceptButton) {
acceptTempLayout.setVisibility(View.VISIBLE);
acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
} else {
acceptTempLayout.setVisibility(View.GONE);
}
// **** Temp button **** // **** Temp button ****
PumpInterface pump = MainApp.getConfigBuilder().getActivePump(); PumpInterface pump = MainApp.getConfigBuilder().getActivePump();
@ -379,6 +485,7 @@ public class OverviewFragment extends Fragment implements PluginBase {
super(x, y); super(x, y);
this.isTempBasal = isTempBasal; this.isTempBasal = isTempBasal;
} }
public boolean isTempBasal = false; public boolean isTempBasal = false;
} }

View file

@ -66,13 +66,10 @@ public class SafetyFragment extends Fragment implements PluginBase, ConstraintsI
* Constraints interface * Constraints interface
**/ **/
@Override @Override
public boolean isAutomaticProcessingEnabled() { public boolean isClosedModeEnabled() {
return true; SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
} String mode = SP.getString("aps_mode", "open");
return mode.equals("closed");
@Override
public boolean manualConfirmationNeeded() {
return false;
} }
@Override @Override

View file

@ -0,0 +1,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="@color/colorCancelTempButton" />
<stroke android:width="1dip" android:color="@android:color/white"/>
<corners
android:radius="2dp" >
</corners>
</shape>

View file

@ -30,12 +30,32 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="vertical"> android:orientation="vertical">
<TextView <LinearLayout
android:id="@+id/overview_timeago" android:orientation="horizontal"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginLeft="10dp"
android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView
android:id="@+id/overview_timeago"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_weight="0.5" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Medium Text"
android:id="@+id/overview_apsmode"
android:layout_marginRight="10dp"
android:background="@drawable/loopmodeborder"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:gravity="center_vertical|center_horizontal" />
</LinearLayout>
<TextView <TextView
android:id="@+id/overview_delta" android:id="@+id/overview_delta"
@ -66,6 +86,22 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="160dip" /> android:layout_height="160dip" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/overview_accepttemplayout">
<Button
android:id="@+id/overview_accepttempbutton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="0.5"
android:text="Accept new temp\n0.25U/h"
android:textColor="@color/colorAcceptTempButton" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/overview_canceltemplayout" android:id="@+id/overview_canceltemplayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -79,8 +115,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" android:layout_margin="10dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:textColor="@color/colorCancelTempButton" android:text="Cancel temp basal"
android:text="Cancel temp basal" /> android:textColor="@color/colorCancelTempButton" />
</LinearLayout> </LinearLayout>
@ -97,8 +133,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" android:layout_margin="10dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:textColor="@color/colorSetTempButton" android:text="TempBasal"
android:text="TempBasal" /> android:textColor="@color/colorSetTempButton" />
<Button <Button
android:id="@+id/overview_extendedbolus" android:id="@+id/overview_extendedbolus"
@ -107,8 +143,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" android:layout_margin="10dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:textColor="@color/colorSetExtendedButton" android:text="Extended Bolus"
android:text="Extended Bolus" /> android:textColor="@color/colorSetExtendedButton" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@ -123,8 +159,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" android:layout_margin="10dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:textColor="@color/colorTreatmentButton" android:text="@string/overview_treatment_label"
android:text="@string/overview_treatment_label" /> android:textColor="@color/colorTreatmentButton" />
<Button <Button
android:id="@+id/overview_wizard" android:id="@+id/overview_wizard"
@ -133,8 +169,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10dp" android:layout_margin="10dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:textColor="@color/colorWizardButton" android:text="@string/overview_calculator_label"
android:text="@string/overview_calculator_label" /> android:textColor="@color/colorWizardButton" />
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="aps_modeArray">
<item>@string/closedloop</item>
<item>@string/openloop</item>
</string-array>
<string-array name="aps_modeValues">
<item>closed</item>
<item>open</item>
</string-array>
</resources>

View file

@ -9,9 +9,10 @@
<color name="linearBlockBackground">#3e3d3d</color> <color name="linearBlockBackground">#3e3d3d</color>
<color name="colorAcceptTempButton">#f4d700</color>
<color name="colorTreatmentButton">#FFB347</color> <color name="colorTreatmentButton">#FFB347</color>
<color name="colorWizardButton">#77dd77</color> <color name="colorWizardButton">#77dd77</color>
<color name="colorCancelTempButton">#FF47C8FF</color> <color name="colorCancelTempButton">#47c8ff</color>
<color name="colorSetTempButton">#FF478EFF</color> <color name="colorSetTempButton">#FF478EFF</color>
<color name="colorSetExtendedButton">#FFDD7792</color> <color name="colorSetExtendedButton">#FFDD7792</color>

View file

@ -106,8 +106,6 @@
<string name="minimalduration">Minimal duration</string> <string name="minimalduration">Minimal duration</string>
<string name="configbuilder_constraints">Constraints</string> <string name="configbuilder_constraints">Constraints</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="loop">Loop</string> <string name="loop">Loop</string>
<string name="configbuilder_loop">Loop</string> <string name="configbuilder_loop">Loop</string>
<string name="loop_aps_label">APS</string> <string name="loop_aps_label">APS</string>
@ -132,7 +130,7 @@
<string name="treatmentdeliveryerror">Treatment delivery error</string> <string name="treatmentdeliveryerror">Treatment delivery error</string>
<string name="overview_newtempbasal_basal_label">Basal value</string> <string name="overview_newtempbasal_basal_label">Basal value</string>
<string name="overview_newtempbasal_percent_label">% (100% = current)</string> <string name="overview_newtempbasal_percent_label">% (100% = current)</string>
<string name="setbasalquestion">Set new temp basal:</string> <string name="setbasalquestion">Accept new temp basal:</string>
<string name="overview_treatment_label">Treatment</string> <string name="overview_treatment_label">Treatment</string>
<string name="overview_calculator_label">Calculator</string> <string name="overview_calculator_label">Calculator</string>
<string name="constraintapllied">Constraint applied!</string> <string name="constraintapllied">Constraint applied!</string>
@ -146,5 +144,10 @@
<string name="configbuilder_bgsource">BG Source</string> <string name="configbuilder_bgsource">BG Source</string>
<string name="xdrip">xDrip</string> <string name="xdrip">xDrip</string>
<string name="nsclient">NSClient</string> <string name="nsclient">NSClient</string>
<string name="apsmode_title">APS Mode</string>
<string name="apsmode_summary">APS Loop Mode</string>
<string name="closedloop">Closed Loop</string>
<string name="openloop">Open Loop</string>
<string name="openloop_newsuggestion">New suggestion available</string>
</resources> </resources>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="aps_general"
android:title="General">
<ListPreference
android:title="@string/apsmode_title"
android:key="aps_mode"
android:defaultValue="open"
android:summary="@string/apsmode_summary"
android:entries="@array/aps_modeArray"
android:entryValues="@array/aps_modeValues"/>
</PreferenceCategory>
</PreferenceScreen>