show predictions in graph
This commit is contained in:
parent
93b80746c6
commit
e9b900d74a
8 changed files with 152 additions and 116 deletions
|
@ -37,7 +37,7 @@
|
|||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
@ -14,7 +14,7 @@ import info.nightscout.client.data.NSProfile;
|
|||
import info.nightscout.utils.DecimalFormatter;
|
||||
import info.nightscout.utils.Round;
|
||||
|
||||
public class PumpEnactResult extends Object implements Parcelable {
|
||||
public class PumpEnactResult extends Object {
|
||||
public boolean success = false; // request was processed successfully (but possible no change was needed)
|
||||
public boolean enacted = false; // request was processed successfully and change has been made
|
||||
public String comment = "";
|
||||
|
@ -85,43 +85,6 @@ public class PumpEnactResult extends Object implements Parcelable {
|
|||
return Html.fromHtml(ret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(success ? 1 : 0);
|
||||
dest.writeInt(enacted ? 1 : 0);
|
||||
dest.writeInt(isPercent ? 1 : 0);
|
||||
dest.writeString(comment);
|
||||
dest.writeInt(duration);
|
||||
dest.writeDouble(absolute);
|
||||
dest.writeInt(percent);
|
||||
}
|
||||
|
||||
public final Parcelable.Creator<PumpEnactResult> CREATOR = new Parcelable.Creator<PumpEnactResult>() {
|
||||
public PumpEnactResult createFromParcel(Parcel in) {
|
||||
return new PumpEnactResult(in);
|
||||
}
|
||||
|
||||
public PumpEnactResult[] newArray(int size) {
|
||||
return new PumpEnactResult[size];
|
||||
}
|
||||
};
|
||||
|
||||
protected PumpEnactResult(Parcel in) {
|
||||
success = in.readInt() == 1 ? true : false;
|
||||
enacted = in.readInt() == 1 ? true : false;
|
||||
isPercent = in.readInt() == 1 ? true : false;
|
||||
duration = in.readInt();
|
||||
comment = in.readString();
|
||||
absolute = in.readDouble();
|
||||
percent = in.readInt();
|
||||
|
||||
}
|
||||
|
||||
public PumpEnactResult() {
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import info.nightscout.utils.DecimalFormatter;
|
|||
/**
|
||||
* Created by mike on 09.06.2016.
|
||||
*/
|
||||
public class APSResult implements Parcelable {
|
||||
public class APSResult {
|
||||
public String reason;
|
||||
public double rate;
|
||||
public int duration;
|
||||
|
@ -51,36 +51,6 @@ public class APSResult implements Parcelable {
|
|||
return Html.fromHtml(MainApp.sResources.getString(R.string.nochangerequested));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(reason);
|
||||
dest.writeDouble(rate);
|
||||
dest.writeInt(duration);
|
||||
dest.writeInt(changeRequested ? 1 : 0);
|
||||
}
|
||||
|
||||
public final Parcelable.Creator<APSResult> CREATOR = new Parcelable.Creator<APSResult>() {
|
||||
public APSResult createFromParcel(Parcel in) {
|
||||
return new APSResult(in);
|
||||
}
|
||||
|
||||
public APSResult[] newArray(int size) {
|
||||
return new APSResult[size];
|
||||
}
|
||||
};
|
||||
|
||||
protected APSResult(Parcel in) {
|
||||
reason = in.readString();
|
||||
rate = in.readDouble();
|
||||
duration = in.readInt();
|
||||
changeRequested = in.readInt() == 1;
|
||||
}
|
||||
|
||||
public APSResult() {
|
||||
}
|
||||
|
||||
|
|
|
@ -93,8 +93,7 @@ public class DetermineBasalAdapterAMAJS {
|
|||
|
||||
|
||||
String ret = mV8rt.executeStringScript("JSON.stringify(rT);");
|
||||
if (Config.logAPSResult)
|
||||
log.debug("Result: " + ret);
|
||||
log.debug("Result: " + ret);
|
||||
|
||||
V8Object v8ObjectReuslt = mV8rt.getObject("rT");
|
||||
|
||||
|
|
|
@ -5,20 +5,27 @@ import android.os.Parcelable;
|
|||
|
||||
import com.eclipsesource.v8.V8Object;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.plugins.Loop.APSResult;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
|
||||
public class DetermineBasalResultAMA extends APSResult {
|
||||
|
||||
public Date date;
|
||||
public JSONObject json = new JSONObject();
|
||||
public double eventualBG;
|
||||
public double snoozeBG;
|
||||
public IobTotal iob;
|
||||
|
||||
public DetermineBasalResultAMA(V8Object result, JSONObject j) {
|
||||
date = new Date();
|
||||
json = j;
|
||||
if (result.contains("error")) {
|
||||
reason = result.getString("error");
|
||||
|
@ -69,6 +76,7 @@ public class DetermineBasalResultAMA extends APSResult {
|
|||
}
|
||||
newResult.eventualBG = eventualBG;
|
||||
newResult.snoozeBG = snoozeBG;
|
||||
newResult.date = date;
|
||||
return newResult;
|
||||
}
|
||||
|
||||
|
@ -83,4 +91,69 @@ public class DetermineBasalResultAMA extends APSResult {
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<BgReading> getPredictions() {
|
||||
List<BgReading> array = new ArrayList<>();
|
||||
try {
|
||||
long startTime = date.getTime();
|
||||
if (json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
for (int i = 1; i < iob.length(); i ++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.timeIndex = startTime + i * 5 * 60 * 1000L;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
||||
for (int i = 1; i < iob.length(); i ++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.timeIndex = startTime + i * 5 * 60 * 1000L;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("COB");
|
||||
for (int i = 1; i < iob.length(); i ++) {
|
||||
BgReading bg = new BgReading();
|
||||
bg.value = iob.getInt(i);
|
||||
bg.timeIndex = startTime + i * 5 * 60 * 1000L;
|
||||
array.add(bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public long getLatestPredictionsTime() {
|
||||
long latest = 0;
|
||||
try {
|
||||
long startTime = date.getTime();
|
||||
if (json.has("predBGs")) {
|
||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
||||
if (predBGs.has("IOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("aCOB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
if (predBGs.has("COB")) {
|
||||
JSONArray iob = predBGs.getJSONArray("COB");
|
||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return latest;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,37 +53,6 @@ public class DetermineBasalResultMA extends APSResult {
|
|||
result.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeString(json.toString());
|
||||
dest.writeDouble(eventualBG);
|
||||
dest.writeDouble(snoozeBG);
|
||||
dest.writeString(mealAssist);
|
||||
}
|
||||
|
||||
public final Parcelable.Creator<DetermineBasalResultMA> CREATOR = new Parcelable.Creator<DetermineBasalResultMA>() {
|
||||
public DetermineBasalResultMA createFromParcel(Parcel in) {
|
||||
return new DetermineBasalResultMA(in);
|
||||
}
|
||||
|
||||
public DetermineBasalResultMA[] newArray(int size) {
|
||||
return new DetermineBasalResultMA[size];
|
||||
}
|
||||
};
|
||||
|
||||
private DetermineBasalResultMA(Parcel in) {
|
||||
super(in);
|
||||
try {
|
||||
json = new JSONObject(in.readString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
eventualBG = in.readDouble();
|
||||
snoozeBG = in.readDouble();
|
||||
mealAssist = in.readString();
|
||||
}
|
||||
|
||||
public DetermineBasalResultMA() {
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -50,6 +52,7 @@ import info.nightscout.androidaps.Constants;
|
|||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.TempBasal;
|
||||
|
@ -69,12 +72,13 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
|||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||
import info.nightscout.androidaps.plugins.Objectives.ObjectivesPlugin;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter;
|
||||
import info.nightscout.client.data.NSProfile;
|
||||
import info.nightscout.utils.BolusWizard;
|
||||
|
@ -106,6 +110,7 @@ public class OverviewFragment extends Fragment {
|
|||
TextView iobView;
|
||||
TextView apsModeView;
|
||||
GraphView bgGraph;
|
||||
CheckBox showPredictionView;
|
||||
|
||||
RecyclerView notificationsView;
|
||||
LinearLayoutManager llm;
|
||||
|
@ -162,12 +167,25 @@ public class OverviewFragment extends Fragment {
|
|||
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
|
||||
quickWizardButton = (Button) view.findViewById(R.id.overview_quickwizard);
|
||||
quickWizardLayout = (LinearLayout) view.findViewById(R.id.overview_quickwizardlayout);
|
||||
showPredictionView = (CheckBox) view.findViewById(R.id.overview_showprediction);
|
||||
|
||||
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
|
||||
notificationsView.setHasFixedSize(true);
|
||||
llm = new LinearLayoutManager(view.getContext());
|
||||
notificationsView.setLayoutManager(llm);
|
||||
|
||||
showPredictionView.setChecked(prefs.getBoolean("showprediction", false));
|
||||
|
||||
showPredictionView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean("showprediction", showPredictionView.isChecked());
|
||||
editor.apply();
|
||||
updateGUI();
|
||||
}
|
||||
});
|
||||
|
||||
treatmentButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
@ -613,6 +631,13 @@ public class OverviewFragment extends Fragment {
|
|||
+ getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)";
|
||||
iobView.setText(iobtext);
|
||||
|
||||
boolean showPrediction = showPredictionView.isChecked() && finalLastRun != null && finalLastRun.constraintsProcessed.getClass().equals(DetermineBasalResultAMA.class);
|
||||
if (MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class) != null && MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class).isEnabled(PluginBase.APS)) {
|
||||
showPredictionView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
showPredictionView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// ****** GRAPH *******
|
||||
|
||||
// allign to hours
|
||||
|
@ -623,9 +648,21 @@ public class OverviewFragment extends Fragment {
|
|||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.add(Calendar.HOUR, 1);
|
||||
|
||||
int hoursToFetch = 6;
|
||||
long toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding
|
||||
long fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
||||
int hoursToFetch;
|
||||
long toTime;
|
||||
long fromTime;
|
||||
long endTime;
|
||||
if (showPrediction) {
|
||||
hoursToFetch = 3;
|
||||
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding
|
||||
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
||||
endTime = toTime + hoursToFetch * 60 * 60 * 1000L;
|
||||
} else {
|
||||
hoursToFetch = 6;
|
||||
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding
|
||||
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
||||
endTime = toTime;
|
||||
}
|
||||
|
||||
Double lowLine = SafeParse.stringToDouble(prefs.getString("low_mark", "0"));
|
||||
Double highLine = SafeParse.stringToDouble(prefs.getString("high_mark", "0"));
|
||||
|
@ -644,6 +681,7 @@ public class OverviewFragment extends Fragment {
|
|||
LineGraphSeries<DataPoint> seriesNow = null;
|
||||
PointsGraphSeries<BgReading> seriesInRage = null;
|
||||
PointsGraphSeries<BgReading> seriesOutOfRange = null;
|
||||
PointsGraphSeries<BgReading> predSeries = null;
|
||||
PointsWithLabelGraphSeries<Treatment> seriesTreatments = null;
|
||||
|
||||
// remove old data from graph
|
||||
|
@ -652,11 +690,11 @@ public class OverviewFragment extends Fragment {
|
|||
// **** HIGH and LOW targets graph ****
|
||||
DataPoint[] lowDataPoints = new DataPoint[]{
|
||||
new DataPoint(fromTime, lowLine),
|
||||
new DataPoint(toTime, lowLine)
|
||||
new DataPoint(endTime, lowLine)
|
||||
};
|
||||
DataPoint[] highDataPoints = new DataPoint[]{
|
||||
new DataPoint(fromTime, highLine),
|
||||
new DataPoint(toTime, highLine)
|
||||
new DataPoint(endTime, highLine)
|
||||
};
|
||||
bgGraph.addSeries(seriesLow = new LineGraphSeries<DataPoint>(lowDataPoints));
|
||||
seriesLow.setColor(Color.RED);
|
||||
|
@ -673,7 +711,6 @@ public class OverviewFragment extends Fragment {
|
|||
public boolean isTempBasal = false;
|
||||
}
|
||||
|
||||
Double maxAllowedBasal = MainApp.getConfigBuilder().applyBasalConstraints(Constants.basalAbsoluteOnlyForCheckLimit);
|
||||
Double maxBasalValueFound = 0d;
|
||||
|
||||
long now = new Date().getTime();
|
||||
|
@ -702,7 +739,7 @@ public class OverviewFragment extends Fragment {
|
|||
}
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
bgGraph.getViewport().setMaxX(toTime);
|
||||
bgGraph.getViewport().setMaxX(endTime);
|
||||
bgGraph.getViewport().setMinX(fromTime);
|
||||
bgGraph.getViewport().setXAxisBoundsManual(true);
|
||||
bgGraph.getGridLabelRenderer().setLabelFormatter(new TimeAsXAxisLabelFormatter(getActivity(), "HH"));
|
||||
|
@ -751,6 +788,19 @@ public class OverviewFragment extends Fragment {
|
|||
seriesOutOfRange.setColor(Color.RED);
|
||||
}
|
||||
|
||||
if (showPrediction) {
|
||||
DetermineBasalResultAMA amaResult = (DetermineBasalResultAMA) finalLastRun.constraintsProcessed;
|
||||
List<BgReading> predArray = amaResult.getPredictions();
|
||||
BgReading[] pred = new BgReading[predArray.size()];
|
||||
pred = predArray.toArray(pred);
|
||||
if (pred.length > 0) {
|
||||
bgGraph.addSeries(predSeries = new PointsGraphSeries<BgReading>(pred));
|
||||
predSeries.setShape(PointsGraphSeries.Shape.POINT);
|
||||
predSeries.setSize(4);
|
||||
predSeries.setColor(Color.MAGENTA);
|
||||
}
|
||||
}
|
||||
|
||||
// **** NOW line ****
|
||||
DataPoint[] nowPoints = new DataPoint[]{
|
||||
new DataPoint(now, 0),
|
||||
|
|
|
@ -150,10 +150,22 @@
|
|||
android:layout_gravity="center_horizontal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<com.jjoe64.graphview.GraphView
|
||||
android:id="@+id/overview_bggraph"
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="160dip" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.jjoe64.graphview.GraphView
|
||||
android:id="@+id/overview_bggraph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="160dip" />
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/overview_showprediction"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/overview_accepttemplayout"
|
||||
|
|
Loading…
Reference in a new issue