From e1dc69cd4d8b5263ba47319d3fc1a255cabdaa61 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 19 Apr 2018 22:31:07 +0200 Subject: [PATCH] visualize min carbs absorption --- .../nightscout/androidaps/db/BgReading.java | 3 +- .../IobCobCalculator/AutosensData.java | 61 +++++++++++++++-- .../IobCobCalculator/IobCobThread.java | 6 +- .../plugins/Overview/graphData/GraphData.java | 7 ++ .../PointsWithLabelGraphSeries.java | 67 ++++++++++--------- 5 files changed, 103 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index e842979ecb..20b9040065 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -195,8 +195,7 @@ public class BgReading implements DataPointWithLabelInterface { @Override public float getSize() { - boolean isTablet = MainApp.sResources.getBoolean(R.bool.isTablet); - return isTablet ? 8 : 5; + return 1; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java index 11b86c5fc5..97ea10b1a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java @@ -11,18 +11,20 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; -import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; +import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; +import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; +import info.nightscout.androidaps.plugins.Treatments.Treatment; import info.nightscout.utils.SP; /** * Created by mike on 25.04.2017. */ -public class AutosensData { +public class AutosensData implements DataPointWithLabelInterface { private static Logger log = LoggerFactory.getLogger(AutosensData.class); static class CarbsInPast { @@ -66,11 +68,11 @@ public class AutosensData { public double slopeFromMaxDeviation = 0; public double slopeFromMinDeviation = 999; public double usedMinCarbsImpact = 0d; - + public boolean failoverToMinAbsorbtionRate = false; @Override public String toString() { - return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ; + return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation; } public int minOld() { @@ -91,7 +93,7 @@ public class AutosensData { activeCarbsList.remove(i--); if (c.remaining > 0) cob -= c.remaining; - log.debug("Removing carbs at "+ new Date(toTime).toLocaleString() + " + after "+ maxAbsorptionHours +"h :" + new Date(c.time).toLocaleString()); + log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString()); } } } @@ -108,4 +110,51 @@ public class AutosensData { } } + // ------- DataPointWithLabelInterface ------ + + @Override + public double getX() { + return time; + } + + @Override + public double getY() { + return cob; + } + + @Override + public void setY(double y) { + + } + + @Override + public String getLabel() { + return null; + } + + @Override + public long getDuration() { + return 0; + } + + @Override + public PointsWithLabelGraphSeries.Shape getShape() { + return PointsWithLabelGraphSeries.Shape.COBFAILOVER; + } + + @Override + public float getSize() { + return 1f; + } + + @Override + public int getColor() { + return MainApp.gc(R.color.cob); + } + + @Override + public int getSecondColor() { + return 0; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index 60d315a070..e1616112ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -20,13 +20,13 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults; import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.Treatments.Treatment; -import info.nightscout.androidaps.events.Event; -import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; @@ -218,6 +218,8 @@ public class IobCobThread extends Thread { // figure out how many carbs that represents // but always assume at least 3mg/dL/5m (default) absorption per active treatment double ci = Math.max(deviation, totalMinCarbsImpact); + if (ci != deviation) + autosensData.failoverToMinAbsorbtionRate = true; autosensData.absorbed = ci * profile.getIc(bgTime) / sens; // and add that to the running total carbsAbsorbed autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java index 9921d236a1..7cae0bd284 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphData/GraphData.java @@ -365,6 +365,7 @@ public class GraphData { // scale in % of vertical size (like 0.3) public void addCob(long fromTime, long toTime, boolean useForScale, double scale) { + List minFailoverActiveList = new ArrayList<>(); FixedLineGraphSeries cobSeries; List cobArray = new ArrayList<>(); Double maxCobValueFound = 0d; @@ -382,6 +383,8 @@ public class GraphData { maxCobValueFound = Math.max(maxCobValueFound, cob); lastCob = cob; } + if (autosensData.failoverToMinAbsorbtionRate) + minFailoverActiveList.add(autosensData); } } @@ -400,6 +403,10 @@ public class GraphData { cobScale.setMultiplier(maxY * scale / maxCobValueFound); addSeries(cobSeries); + + DataPointWithLabelInterface[] minFailover = new DataPointWithLabelInterface[minFailoverActiveList.size()]; + minFailover = minFailoverActiveList.toArray(minFailover); + addSeries(new PointsWithLabelGraphSeries<>(minFailover)); } // scale in % of vertical size (like 0.3) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java index 9c8e312fb6..8ac3be0ad8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -3,42 +3,46 @@ package info.nightscout.androidaps.plugins.Overview.graphExtensions; /** * GraphView * Copyright (C) 2014 Jonas Gehring - * + *

* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, * with the "Linking Exception", which can be found at the license.txt * file in this program. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + *

* You should have received a copy of the GNU General Public License * with the "Linking Exception" along with this program; if not, * write to the author Jonas Gehring . + *

+ * Added by mike */ /** * Added by mike */ +import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Typeface; -import android.util.TypedValue; -// Added by Rumen for scalable text -import android.content.Context; -import info.nightscout.androidaps.MainApp; + import com.jjoe64.graphview.GraphView; import com.jjoe64.graphview.series.BaseSeries; import java.util.Iterator; +import info.nightscout.androidaps.MainApp; + +// Added by Rumen for scalable text + /** * Series that plots the data as points. * The points can be different shapes or a @@ -74,7 +78,8 @@ public class PointsWithLabelGraphSeries e OPENAPSOFFLINE, EXERCISE, GENERAL, - GENERALWITHDURATION + GENERALWITHDURATION, + COBFAILOVER } /** @@ -148,7 +153,7 @@ public class PointsWithLabelGraphSeries e float scaleX = (float) (graphWidth / diffX); - int i=0; + int i = 0; while (values.hasNext()) { E value = values.next(); @@ -182,7 +187,7 @@ public class PointsWithLabelGraphSeries e } /* Fix a bug that continue to show the DOT after Y axis */ - if(x < 0) { + if (x < 0) { overdraw = true; } @@ -197,10 +202,10 @@ public class PointsWithLabelGraphSeries e // draw data point if (!overdraw) { - if (value.getShape() == Shape.BG) { + if (value.getShape() == Shape.BG || value.getShape() == Shape.COBFAILOVER) { mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeWidth(0); - canvas.drawCircle(endX, endY, scaledPxSize, mPaint); + canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint); } else if (value.getShape() == Shape.PREDICTION) { mPaint.setColor(value.getColor()); mPaint.setStyle(Paint.Style.FILL); @@ -211,20 +216,20 @@ public class PointsWithLabelGraphSeries e mPaint.setStrokeWidth(0); canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint); } else if (value.getShape() == Shape.RECTANGLE) { - canvas.drawRect(endX-scaledPxSize, endY-scaledPxSize, endX+scaledPxSize, endY+scaledPxSize, mPaint); + canvas.drawRect(endX - scaledPxSize, endY - scaledPxSize, endX + scaledPxSize, endY + scaledPxSize, mPaint); } else if (value.getShape() == Shape.TRIANGLE) { mPaint.setStrokeWidth(0); Point[] points = new Point[3]; - points[0] = new Point((int)endX, (int)(endY-scaledPxSize)); - points[1] = new Point((int)(endX+scaledPxSize), (int)(endY+scaledPxSize*0.67)); - points[2] = new Point((int)(endX-scaledPxSize), (int)(endY+scaledPxSize*0.67)); + points[0] = new Point((int) endX, (int) (endY - scaledPxSize)); + points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67)); + points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67)); drawArrows(points, canvas, mPaint); } else if (value.getShape() == Shape.BOLUS) { mPaint.setStrokeWidth(0); Point[] points = new Point[3]; - points[0] = new Point((int)endX, (int)(endY-scaledPxSize)); - points[1] = new Point((int)(endX+scaledPxSize), (int)(endY+scaledPxSize*0.67)); - points[2] = new Point((int)(endX-scaledPxSize), (int)(endY+scaledPxSize*0.67)); + points[0] = new Point((int) endX, (int) (endY - scaledPxSize)); + points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67)); + points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67)); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); drawArrows(points, canvas, mPaint); if (value.getLabel() != null) { @@ -234,15 +239,15 @@ public class PointsWithLabelGraphSeries e mPaint.setStrokeWidth(2); Point[] points = new Point[3]; float size = value.getSize() * scaledPxSize; - points[0] = new Point((int)endX, (int)(endY-size)); - points[1] = new Point((int)(endX+size), (int)(endY+size*0.67)); - points[2] = new Point((int)(endX-size), (int)(endY+size*0.67)); + points[0] = new Point((int) endX, (int) (endY - size)); + points[1] = new Point((int) (endX + size), (int) (endY + size * 0.67)); + points[2] = new Point((int) (endX - size), (int) (endY + size * 0.67)); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); drawArrows(points, canvas, mPaint); } else if (value.getShape() == Shape.EXTENDEDBOLUS) { mPaint.setStrokeWidth(0); if (value.getLabel() != null) { - Rect bounds = new Rect((int)endX, (int)endY + 3, (int) (xpluslength), (int) endY + 8); + Rect bounds = new Rect((int) endX, (int) endY + 3, (int) (xpluslength), (int) endY + 8); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawRect(bounds, mPaint); mPaint.setTextSize((float) (scaledTextSize)); @@ -254,7 +259,7 @@ public class PointsWithLabelGraphSeries e mPaint.setStrokeWidth(0); if (value.getLabel() != null) { //mPaint.setTextSize((int) (scaledPxSize * 3)); - mPaint.setTextSize((float) (scaledTextSize*1.2)); + mPaint.setTextSize((float) (scaledTextSize * 1.2)); mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); Rect bounds = new Rect(); mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds); @@ -355,7 +360,7 @@ public class PointsWithLabelGraphSeries e * @param paint paint object */ private void drawArrows(Point[] point, Canvas canvas, Paint paint) { - float [] points = new float[8]; + float[] points = new float[8]; points[0] = point[0].x; points[1] = point[0].y; points[2] = point[1].x; @@ -368,10 +373,10 @@ public class PointsWithLabelGraphSeries e canvas.save(); canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint); Path path = new Path(); - path.moveTo(point[0].x , point[0].y); - path.lineTo(point[1].x,point[1].y); - path.lineTo(point[2].x,point[2].y); - canvas.drawPath(path,paint); + path.moveTo(point[0].x, point[0].y); + path.lineTo(point[1].x, point[1].y); + path.lineTo(point[2].x, point[2].y); + canvas.drawPath(path, paint); canvas.restore(); } @@ -381,7 +386,7 @@ public class PointsWithLabelGraphSeries e float py = endY + scaledPxSize; canvas.save(); canvas.rotate(-45, px, py); - mPaint.setTextSize((float) (scaledTextSize*0.8)); + mPaint.setTextSize((float) (scaledTextSize * 0.8)); mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)); mPaint.setFakeBoldText(true); mPaint.setTextAlign(Paint.Align.RIGHT); @@ -393,7 +398,7 @@ public class PointsWithLabelGraphSeries e float py = endY - scaledPxSize; canvas.save(); canvas.rotate(-45, px, py); - mPaint.setTextSize((float) (scaledTextSize*0.8)); + mPaint.setTextSize((float) (scaledTextSize * 0.8)); mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)); mPaint.setFakeBoldText(true); canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);