From c6a3efb60e2db4959769c23a2b2997d6ffa6fb33 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 21 Feb 2018 14:23:52 +0100 Subject: [PATCH] wear adaptive prediction timeframe --- .../wearintegration/WatchUpdaterService.java | 23 +++++++++ .../androidaps/data/BgWatchData.java | 4 ++ .../androidaps/watchfaces/BIGChart.java | 16 ++++++- .../androidaps/watchfaces/BaseWatchFace.java | 5 +- .../androidaps/watchfaces/BgGraphBuilder.java | 47 +++++++++++++++++-- 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java index 60a8a27bea..2091f2ad84 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/wearintegration/WatchUpdaterService.java @@ -356,6 +356,8 @@ public class WatchUpdaterService extends WearableListenerService implements ArrayList basals = new ArrayList<>(); ArrayList temps = new ArrayList<>(); ArrayList boluses = new ArrayList<>(); + ArrayList predictions = new ArrayList<>(); + @@ -461,10 +463,24 @@ public class WatchUpdaterService extends WearableListenerService implements } } + + final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; + if(finalLastRun != null && finalLastRun.request.hasPredictions && finalLastRun.constraintsProcessed != null){ + List predArray = finalLastRun.constraintsProcessed.getPredictions(); + + if (!predArray.isEmpty()) { + for (BgReading bg : predArray) { + predictions.add(predictionMap(bg.date, bg.value)); + } + } + } + + DataMap dm = new DataMap(); dm.putDataMapArrayList("basals", basals); dm.putDataMapArrayList("temps", temps); dm.putDataMapArrayList("boluses", boluses); + dm.putDataMapArrayList("predictions", predictions); new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient).execute(dm); } @@ -496,6 +512,13 @@ public class WatchUpdaterService extends WearableListenerService implements return dm; } + private DataMap predictionMap(long timestamp, double sgv) { + DataMap dm = new DataMap(); + dm.putLong("timestamp", timestamp); + dm.putDouble("sgv", sgv); + return dm; + } + private void sendNotification() { if (googleApiClient.isConnected()) { diff --git a/wear/src/main/java/info/nightscout/androidaps/data/BgWatchData.java b/wear/src/main/java/info/nightscout/androidaps/data/BgWatchData.java index 54eb597f1a..8f20d77282 100644 --- a/wear/src/main/java/info/nightscout/androidaps/data/BgWatchData.java +++ b/wear/src/main/java/info/nightscout/androidaps/data/BgWatchData.java @@ -16,6 +16,10 @@ public class BgWatchData implements Comparable{ this.timestamp = aTimestamp; } + public BgWatchData(){ + + } + @Override public boolean equals(Object that){ if(! (that instanceof BgWatchData)){ diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BIGChart.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BIGChart.java index b7a3c7769e..4926e924cb 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BIGChart.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BIGChart.java @@ -77,6 +77,8 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre public ArrayList tempWatchDataList = new ArrayList<>(); public ArrayList basalWatchDataList = new ArrayList<>(); public ArrayList bolusWatchDataList = new ArrayList<>(); + public ArrayList predictionList = new ArrayList<>(); + public PowerManager.WakeLock wakeLock; public View layoutView; private final Point displaySize = new Point(); @@ -413,6 +415,16 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre bolusWatchDataList.add(bwd); } } + ArrayList predictions = dataMap.getDataMapArrayList("predictions"); + if (boluses != null) { + predictionList = new ArrayList<>(); + for (DataMap prediction : predictions) { + BgWatchData bwd = new BgWatchData(); + bwd.timestamp = prediction.getLong("timestamp"); + bwd.sgv = prediction.getDouble("sgv"); + predictionList.add(bwd); + } + } } private void showAgeAndStatus() { @@ -655,9 +667,9 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre if(bgDataList.size() > 0) { //Dont crash things just because we dont have values, people dont like crashy things int timeframe = Integer.parseInt(sharedPrefs.getString("chart_timeframe", "3")); if (lowResMode) { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, bolusWatchDataList, pointSize, midColor, gridColour, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, predictionList, tempWatchDataList, basalWatchDataList, bolusWatchDataList, pointSize, midColor, gridColour, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); } else { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, bolusWatchDataList, pointSize, highColor, lowColor, midColor, gridColour, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, predictionList, tempWatchDataList, basalWatchDataList, bolusWatchDataList, pointSize, highColor, lowColor, midColor, gridColour, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); } chart.setLineChartData(bgGraphBuilder.lineData()); diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java index 6b3df4b979..2627258860 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java @@ -76,6 +76,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen public ArrayList bgDataList = new ArrayList<>(); public ArrayList tempWatchDataList = new ArrayList<>(); public ArrayList basalWatchDataList = new ArrayList<>(); + public ArrayList predictionList = new ArrayList<>(); public PowerManager.WakeLock wakeLock; // related endTime manual layout public View layoutView; @@ -629,9 +630,9 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen if(bgDataList.size() > 0) { //Dont crash things just because we dont have values, people dont like crashy things int timeframe = Integer.parseInt(sharedPrefs.getString("chart_timeframe", "3")); if (lowResMode) { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, null, pointSize, midColor, gridColor, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, predictionList, tempWatchDataList, basalWatchDataList, null, pointSize, midColor, gridColor, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); } else { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, basalWatchDataList, null, pointSize, highColor, lowColor, midColor, gridColor, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList,predictionList, tempWatchDataList, basalWatchDataList, null, pointSize, highColor, lowColor, midColor, gridColor, basalBackgroundColor, basalCenterColor, bolusColor, timeframe); } chart.setLineChartData(bgGraphBuilder.lineData()); diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BgGraphBuilder.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BgGraphBuilder.java index 064c00bdcd..a0e46b8390 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BgGraphBuilder.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BgGraphBuilder.java @@ -1,6 +1,7 @@ package info.nightscout.androidaps.watchfaces; import android.content.Context; +import android.graphics.Color; import android.graphics.DashPathEffect; import android.preference.PreferenceManager; import android.text.format.DateFormat; @@ -28,6 +29,8 @@ import lecho.lib.hellocharts.model.Viewport; * Created by emmablack on 11/15/14. */ public class BgGraphBuilder { + public static final double MAX_PREDICTION__TIME_RATIO = (3d / 5); + private List predictionsList; private ArrayList bolusWatchDataList; private ArrayList basalWatchDataList; public List tempWatchDataList; @@ -58,10 +61,11 @@ public class BgGraphBuilder { //used for low resolution screen. - public BgGraphBuilder(Context context, List aBgList, List tempWatchDataList, ArrayList basalWatchDataList, ArrayList bolusWatchDataList, int aPointSize, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int bolusColor, int timespan) { + public BgGraphBuilder(Context context, List aBgList, List predictionsList, List tempWatchDataList, ArrayList basalWatchDataList, ArrayList bolusWatchDataList, int aPointSize, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int bolusColor, int timespan) { end_time = System.currentTimeMillis() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.) start_time = System.currentTimeMillis() - (1000 * 60 * 60 * timespan); //timespan hours ago this.bgDataList = aBgList; + this.predictionsList = predictionsList; this.context = context; this.highMark = aBgList.get(aBgList.size() - 1).high; this.lowMark = aBgList.get(aBgList.size() - 1).low; @@ -80,10 +84,11 @@ public class BgGraphBuilder { this.bolusColor = bolusColor; } - public BgGraphBuilder(Context context, List aBgList, List tempWatchDataList, ArrayList basalWatchDataList, ArrayList bolusWatchDataList, int aPointSize, int aHighColor, int aLowColor, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int bolusColor, int timespan) { + public BgGraphBuilder(Context context, List aBgList, List predictionsList, List tempWatchDataList, ArrayList basalWatchDataList, ArrayList bolusWatchDataList, int aPointSize, int aHighColor, int aLowColor, int aMidColor, int gridColour, int basalBackgroundColor, int basalCenterColor, int bolusColor, int timespan) { end_time = System.currentTimeMillis() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.) start_time = System.currentTimeMillis() - (1000 * 60 * 60 * timespan); //timespan hours ago this.bgDataList = aBgList; + this.predictionsList = predictionsList; this.context = context; this.highMark = aBgList.get(aBgList.size() - 1).high; this.lowMark = aBgList.get(aBgList.size() - 1).low; @@ -109,6 +114,7 @@ public class BgGraphBuilder { } public List defaultLines() { + addBgReadingValues(); List lines = new ArrayList(); lines.add(highLine()); @@ -163,6 +169,7 @@ public class BgGraphBuilder { lines.add(basalLine((float) minChart, factor, highlight)); lines.add(bolusLine((float) minChart)); lines.add(smbLine((float) minChart)); + lines.add(predictionLine()); return lines; @@ -224,6 +231,24 @@ public class BgGraphBuilder { return line; } + private Line predictionLine() { + + List pointValues = new ArrayList(); + + long endTime = getPredictionEndTime(); + for (BgWatchData bwd: predictionsList) { + if(bwd.timestamp <= endTime) { + pointValues.add(new PointValue(fuzz(bwd.timestamp), (float) bwd.sgv)); + } + } + Line line = new Line(pointValues); + line.setColor(Color.MAGENTA); + line.setHasLines(false); + line.setPointRadius(pointSize); + line.setHasPoints(true); + return line; + } + @@ -365,9 +390,12 @@ public class BgGraphBuilder { timeFormat.setTimeZone(TimeZone.getDefault()); long start_hour = today.getTime().getTime(); long timeNow = System.currentTimeMillis(); + + long endTime = getPredictionEndTime(); + for (int l = 0; l <= 24; l++) { - if ((start_hour + (60000 * 60 * (l))) < timeNow) { - if ((start_hour + (60000 * 60 * (l + 1))) >= timeNow) { + if ((start_hour + (60000 * 60 * (l))) < endTime) { + if ((start_hour + (60000 * 60 * (l + 1))) >= endTime) { endHour = start_hour + (60000 * 60 * (l)); l = 25; } @@ -397,6 +425,17 @@ public class BgGraphBuilder { return xAxis; } + public long getPredictionEndTime() { + long maxPredictionDate = System.currentTimeMillis(); + for (BgWatchData prediction : + predictionsList) { + if (maxPredictionDate < prediction.timestamp) { + maxPredictionDate = prediction.timestamp; + } + } + return (long) Math.min(maxPredictionDate, System.currentTimeMillis() + MAX_PREDICTION__TIME_RATIO *timespan*1000*60*60); + } + public float fuzz(long value) { return (float) Math.round(value / fuzzyTimeDenom); }