diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java index e4cca62d57..2936c4da63 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java @@ -82,7 +82,8 @@ public class WearPlugin implements PluginBase { } if(basals){ - //TODO send basals + ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BASALS)); + } if(status){ 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 43dd6d01fe..27b215e136 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 @@ -40,12 +40,15 @@ public class WatchUpdaterService extends WearableListenerService implements public static final String ACTION_RESEND = WatchUpdaterService.class.getName().concat(".Resend"); public static final String ACTION_OPEN_SETTINGS = WatchUpdaterService.class.getName().concat(".OpenSettings"); public static final String ACTION_SEND_STATUS = WatchUpdaterService.class.getName().concat(".SendStatus"); + public static final String ACTION_SEND_BASALS = WatchUpdaterService.class.getName().concat(".SendBasals"); + private GoogleApiClient googleApiClient; public static final String WEARABLE_DATA_PATH = "/nightscout_watch_data"; public static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend"; private static final String OPEN_SETTINGS_PATH = "/openwearsettings"; private static final String NEW_STATUS_PATH = "/sendstatustowear"; + public static final String BASAL_DATA_PATH = "/nightscout_watch_basal"; boolean wear_integration = false; @@ -107,6 +110,8 @@ public class WatchUpdaterService extends WearableListenerService implements sendNotification(); } else if (ACTION_SEND_STATUS.equals(action)) { sendStatus(); + } else if (ACTION_SEND_BASALS.equals(action)) { + sendBasals(); } else { sendData(); } @@ -236,6 +241,75 @@ public class WatchUpdaterService extends WearableListenerService implements entries.putDataMapArrayList("entries", dataMaps); new SendToDataLayerThread(WEARABLE_DATA_PATH, googleApiClient).execute(entries); } + sendBasals(); + sendStatus(); + } + + private void sendBasals() { + if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } + long startTime = System.currentTimeMillis() - (long)(60000 * 60 * 5.5); + + + ArrayList basals = new ArrayList<>(); + + + //TODO: Adrian: replace fake data + long from = startTime; + long to = (System.currentTimeMillis()+ startTime)/2; + double amount = 0.5; + double afterwards = 0.8; + basals.add(basalMap(from, to, amount, afterwards)); + + from = to; + to = System.currentTimeMillis(); + amount = 0.8; + basals.add(basalMap(from, to, amount, amount)); + + + + ArrayList temps = new ArrayList<>(); + from = (long)(startTime + (1/8d)*(to - startTime)); + double fromBasal = 0.5; + to = (long)(startTime + (2/8d)*(to - startTime)); + double toBasal = 0.5; + amount = 3; + temps.add(tempDatamap(from, fromBasal, to, toBasal, amount)); + + + from = (long)(startTime + (6/8d)*(to - startTime)); + fromBasal = 0; + to = (long)(startTime + (7/8d)*(to - startTime)); + toBasal = 0; + amount = 0; + temps.add(tempDatamap(from, fromBasal, to, toBasal, amount)); + + + + + DataMap dm = new DataMap(); + dm.putDataMapArrayList("basals", basals); + dm.putDataMapArrayList("temps", temps); + + new SendToDataLayerThread(BASAL_DATA_PATH, googleApiClient).execute(dm); + } + + private DataMap tempDatamap(long startTime, double startBasal, long to, double toBasal, double amount) { + DataMap dm = new DataMap(); + dm.putLong("starttime", startTime); + dm.putDouble("startBasal", startBasal); + dm.putLong("endtime", to); + dm.putDouble("endbasal", toBasal); + dm.putDouble("amount", amount); + return dm; + } + + private DataMap basalMap(long startTime, long endTime, double amount, double afterwards) { + DataMap dm = new DataMap(); + dm.putLong("starttime", startTime); + dm.putLong("endtime", endTime); + dm.putDouble("amount", amount); + dm.putDouble("afterwards", afterwards); + return dm; } diff --git a/wear/build.gradle b/wear/build.gradle index d09c726980..53251f7db6 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -35,8 +35,9 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.ustwo.android:clockwise-wearable:1.0.2' compile 'com.google.android.support:wearable:1.1.0' compile 'com.google.android.gms:play-services-wearable:7.3.0' + compile files('libs/hellocharts-library-1.5.5.jar') } diff --git a/wear/libs/hellocharts-library-1.1.jar b/wear/libs/hellocharts-library-1.1.jar deleted file mode 100644 index 85b265168b..0000000000 Binary files a/wear/libs/hellocharts-library-1.1.jar and /dev/null differ diff --git a/wear/libs/hellocharts-library-1.5.5.jar b/wear/libs/hellocharts-library-1.5.5.jar new file mode 100644 index 0000000000..142316706e Binary files /dev/null and b/wear/libs/hellocharts-library-1.5.5.jar differ diff --git a/wear/src/main/java/info/nightscout/androidaps/BIGChart.java b/wear/src/main/java/info/nightscout/androidaps/BIGChart.java index c7ee2f30e4..55799bf897 100644 --- a/wear/src/main/java/info/nightscout/androidaps/BIGChart.java +++ b/wear/src/main/java/info/nightscout/androidaps/BIGChart.java @@ -37,7 +37,7 @@ import com.ustwo.clockwise.WatchShape; import java.util.ArrayList; import java.util.Date; -import lecho.lib.hellocharts.util.Utils; +import lecho.lib.hellocharts.util.ChartUtils; import lecho.lib.hellocharts.view.LineChartView; /** @@ -63,8 +63,9 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre public LineChartView chart; public double datetime; public ArrayList bgDataList = new ArrayList<>(); + public ArrayList tempWatchDataList = new ArrayList<>(); public PowerManager.WakeLock wakeLock; - // related to manual layout + // related endTime manual layout public View layoutView; private final Point displaySize = new Point(); private int specW, specH; @@ -264,6 +265,20 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre showAgeAndStatus(); + mRelativeLayout.measure(specW, specH); + mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), + mRelativeLayout.getMeasuredHeight()); + invalidate(); + setColor(); + } + //basals and temps + bundle = intent.getBundleExtra("basals"); + if (layoutSet && bundle != null) { + DataMap dataMap = DataMap.fromBundle(bundle); + wakeLock.acquire(500); + + loadBasalsAndTemps(dataMap); + mRelativeLayout.measure(specW, specH); mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(), mRelativeLayout.getMeasuredHeight()); @@ -273,6 +288,23 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre } } + private void loadBasalsAndTemps(DataMap dataMap) { + ArrayList temps = dataMap.getDataMapArrayList("temps"); + if (temps != null) { + tempWatchDataList = new ArrayList<>(); + for (DataMap temp : temps) { + TempWatchData twd = new TempWatchData(); + twd.startTime = temp.getLong("starttime"); + twd.startBasal = temp.getDouble("startBasal"); + twd.endTime = temp.getLong("endtime"); + twd.endBasal = temp.getDouble("endbasal"); + twd.amount = temp.getDouble("amount"); + tempWatchDataList.add(twd); + } + } + //TODO Adrian: also load temps + } + private void showAgeAndStatus() { if( mTimestamp != null){ @@ -407,8 +439,8 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { mRelativeLayout.setBackgroundColor(Color.WHITE); if (sgvLevel == 1) { - mSgv.setTextColor(Utils.COLOR_ORANGE); - mDelta.setTextColor(Utils.COLOR_ORANGE); + mSgv.setTextColor(ChartUtils.COLOR_ORANGE); + mDelta.setTextColor(ChartUtils.COLOR_ORANGE); } else if (sgvLevel == 0) { mSgv.setTextColor(Color.BLACK); mDelta.setTextColor(Color.BLACK); @@ -427,7 +459,7 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre mTime.setTextColor(Color.BLACK); statusView.setTextColor(Color.BLACK); if (chart != null) { - highColor = Utils.COLOR_ORANGE; + highColor = ChartUtils.COLOR_ORANGE; midColor = Color.BLUE; lowColor = Color.RED; singleLine = false; @@ -471,7 +503,7 @@ public class BIGChart extends WatchFace implements SharedPreferences.OnSharedPre .setVibrate(vibratePattern); NotificationManager mNotifyMgr = (hNotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE); mNotifyMgr.notify(missed_readings_alert_id, notification.build());*/ - ListenerService.requestData(this); // attempt to recover missing data + ListenerService.requestData(this); // attempt endTime recover missing data } } @@ -520,9 +552,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", "5")); if (singleLine) { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, pointSize, midColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, pointSize, midColor, timeframe); } else { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, pointSize, highColor, lowColor, midColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, tempWatchDataList, pointSize, highColor, lowColor, midColor, timeframe); } chart.setLineChartData(bgGraphBuilder.lineData()); diff --git a/wear/src/main/java/info/nightscout/androidaps/BaseWatchFace.java b/wear/src/main/java/info/nightscout/androidaps/BaseWatchFace.java index e127725a66..0541a6c248 100644 --- a/wear/src/main/java/info/nightscout/androidaps/BaseWatchFace.java +++ b/wear/src/main/java/info/nightscout/androidaps/BaseWatchFace.java @@ -59,7 +59,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen public double datetime; public ArrayList bgDataList = new ArrayList<>(); public PowerManager.WakeLock wakeLock; - // related to manual layout + // related endTime manual layout public View layoutView; private final Point displaySize = new Point(); private int specW, specH; @@ -327,7 +327,7 @@ protected abstract void setColorDark(); .setVibrate(vibratePattern); NotificationManager mNotifyMgr = (NotificationManager) getApplicationContext().getSystemService(getApplicationContext().NOTIFICATION_SERVICE); mNotifyMgr.notify(missed_readings_alert_id, notification.build());*/ - ListenerService.requestData(this); // attempt to recover missing data + ListenerService.requestData(this); // attempt endTime recover missing data } } @@ -376,9 +376,9 @@ protected abstract void setColorDark(); 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", "5")); if (singleLine) { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, pointSize, midColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, new ArrayList(), pointSize, midColor, timeframe); } else { - bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, pointSize, highColor, lowColor, midColor, timeframe); + bgGraphBuilder = new BgGraphBuilder(getApplicationContext(), bgDataList, new ArrayList(), pointSize, highColor, lowColor, midColor, timeframe); } chart.setLineChartData(bgGraphBuilder.lineData()); diff --git a/wear/src/main/java/info/nightscout/androidaps/BgGraphBuilder.java b/wear/src/main/java/info/nightscout/androidaps/BgGraphBuilder.java index 01fb281328..006eede27e 100644 --- a/wear/src/main/java/info/nightscout/androidaps/BgGraphBuilder.java +++ b/wear/src/main/java/info/nightscout/androidaps/BgGraphBuilder.java @@ -1,6 +1,8 @@ package info.nightscout.androidaps; import android.content.Context; +import android.graphics.Color; +import android.graphics.DashPathEffect; import android.text.format.DateFormat; import java.text.SimpleDateFormat; @@ -22,6 +24,7 @@ import lecho.lib.hellocharts.model.Viewport; * Created by stephenblack on 11/15/14. */ public class BgGraphBuilder { + public List tempWatchDataList; private int timespan; public double end_time; public double start_time; @@ -43,7 +46,7 @@ public class BgGraphBuilder { private List lowValues = new ArrayList(); public Viewport viewport; - public BgGraphBuilder(Context context, List aBgList, int aPointSize, int aMidColor, int timespan) { + public BgGraphBuilder(Context context, List aBgList, List tempWatchDataList, int aPointSize, int aMidColor, int timespan) { end_time = new Date().getTime() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.) start_time = new Date().getTime() - (1000 * 60 * 60 * timespan); //timespan hours ago this.bgDataList = aBgList; @@ -56,9 +59,10 @@ public class BgGraphBuilder { this.lowColor = aMidColor; this.highColor = aMidColor; this.timespan = timespan; + this.tempWatchDataList = tempWatchDataList; } - public BgGraphBuilder(Context context, List aBgList, int aPointSize, int aHighColor, int aLowColor, int aMidColor, int timespan) { + public BgGraphBuilder(Context context, List aBgList, List tempWatchDataList, int aPointSize, int aHighColor, int aLowColor, int aMidColor, int timespan) { end_time = new Date().getTime() + (1000 * 60 * 6 * timespan); //Now plus 30 minutes padding (for 5 hours. Less if less.) start_time = new Date().getTime() - (1000 * 60 * 60 * timespan); //timespan hours ago this.bgDataList = aBgList; @@ -70,6 +74,7 @@ public class BgGraphBuilder { this.lowColor = aLowColor; this.midColor = aMidColor; this.timespan = timespan; + this.tempWatchDataList = tempWatchDataList; } public LineChartData lineData() { @@ -87,6 +92,34 @@ public class BgGraphBuilder { lines.add(inRangeValuesLine()); lines.add(lowValuesLine()); lines.add(highValuesLine()); + + double minChart = lowMark; + double maxChart = highMark; + + for ( BgWatchData bgd:bgDataList) { + if(bgd.sgv > maxChart){ + maxChart = bgd.sgv; + } + if(bgd.sgv < minChart){ + minChart = bgd.sgv; + } + } + + double maxBasal = 0.8; //TODO Adrian keine Konstante! + double maxTemp = maxBasal; + for (TempWatchData twd: tempWatchDataList) { + if(twd.amount > maxTemp){ + maxTemp = twd.amount; + } + } + + double factor = (maxChart-minChart)/maxTemp; + // in case basal is the highest, don't paint it totally at the top. + factor = Math.min(factor, ((maxChart-minChart)/maxTemp)*(2/3d)); + + lines.add(tempValuesLine((float) minChart, factor)); + + return lines; } @@ -123,6 +156,28 @@ public class BgGraphBuilder { return inRangeValuesLine; } + + public Line tempValuesLine(float offset, double factor) { + List lineValues = new ArrayList(); + + for (TempWatchData twd: tempWatchDataList) { + lineValues.add(new PointValue(fuzz(twd.startTime), offset + (float)(factor*twd.startBasal))); + lineValues.add(new PointValue(fuzz(twd.startTime), offset +(float)(factor*twd.amount))); + lineValues.add(new PointValue(fuzz(twd.endTime), offset + (float)(factor*twd.amount))); + lineValues.add(new PointValue(fuzz(twd.endTime), offset + (float)(factor*twd.endBasal))); + + } + + Line valueLine = new Line(lineValues); + valueLine.setHasPoints(false); + valueLine.setColor(Color.BLUE); + valueLine.setStrokeWidth(1); + return valueLine; + } + + + + private void addBgReadingValues() { if(singleLine) { for (BgWatchData bgReading : bgDataList) { @@ -214,7 +269,7 @@ public class BgGraphBuilder { SimpleDateFormat longTimeFormat = new SimpleDateFormat(is24? "HH:mm" : "h:mm a"); xAxisValues.add(new AxisValue(fuzz(timeNow), (longTimeFormat.format(timeNow)).toCharArray())); - //Add whole hours to the axis (as long as they are more than 15 mins away from the current time) + //Add whole hours endTime the axis (as long as they are more than 15 mins away from the current time) for (int l = 0; l <= 24; l++) { double timestamp = endHour - (60000 * 60 * l); if((timestamp - timeNow < 0) && (timestamp > start_time)) { diff --git a/wear/src/main/java/info/nightscout/androidaps/BgWatchData.java b/wear/src/main/java/info/nightscout/androidaps/BgWatchData.java index 9a6ea01b62..9fa323f226 100644 --- a/wear/src/main/java/info/nightscout/androidaps/BgWatchData.java +++ b/wear/src/main/java/info/nightscout/androidaps/BgWatchData.java @@ -31,7 +31,7 @@ public class BgWatchData implements Comparable{ @Override public int compareTo(BgWatchData that) { - // reverse order to get latest first + // reverse order endTime get latest first if(this.timestamp < that.timestamp) return 1; if(this.timestamp > that.timestamp) return -1; return 0; diff --git a/wear/src/main/java/info/nightscout/androidaps/CircleWatchface.java b/wear/src/main/java/info/nightscout/androidaps/CircleWatchface.java index d4cc9acd06..232716f678 100644 --- a/wear/src/main/java/info/nightscout/androidaps/CircleWatchface.java +++ b/wear/src/main/java/info/nightscout/androidaps/CircleWatchface.java @@ -41,7 +41,7 @@ public class CircleWatchface extends WatchFace implements SharedPreferences.OnSh public final float CIRCLE_WIDTH = 10f; public final int BIG_HAND_WIDTH = 16; public final int SMALL_HAND_WIDTH = 8; - public final int NEAR = 2; //how near do the hands have to be to activate overlapping mode + public final int NEAR = 2; //how near do the hands have endTime be endTime activate overlapping mode public final boolean ALWAYS_HIGHLIGT_SMALL = false; //variables for time @@ -326,7 +326,7 @@ public class CircleWatchface extends WatchFace implements SharedPreferences.OnSh wakeLock.acquire(30000); /*Preparing the layout just on every minute tick: * - hopefully better battery life - * - drawback: might update the minutes since last reading up to one minute late*/ + * - drawback: might update the minutes since last reading up endTime one minute late*/ prepareLayout(); prepareDrawTime(); invalidate(); //redraw the time diff --git a/wear/src/main/java/info/nightscout/androidaps/Home.java b/wear/src/main/java/info/nightscout/androidaps/Home.java index 7d0e78fc3f..de11620020 100644 --- a/wear/src/main/java/info/nightscout/androidaps/Home.java +++ b/wear/src/main/java/info/nightscout/androidaps/Home.java @@ -5,7 +5,7 @@ import android.view.LayoutInflater; import com.ustwo.clockwise.WatchMode; -import lecho.lib.hellocharts.util.Utils; +import lecho.lib.hellocharts.util.ChartUtils; public class Home extends BaseWatchFace { @@ -65,9 +65,9 @@ public class Home extends BaseWatchFace { mRelativeLayout.setBackgroundColor(Color.WHITE); mLinearLayout.setBackgroundColor(Color.BLACK); if (sgvLevel == 1) { - mSgv.setTextColor(Utils.COLOR_ORANGE); - mDirection.setTextColor(Utils.COLOR_ORANGE); - mDelta.setTextColor(Utils.COLOR_ORANGE); + mSgv.setTextColor(ChartUtils.COLOR_ORANGE); + mDirection.setTextColor(ChartUtils.COLOR_ORANGE); + mDelta.setTextColor(ChartUtils.COLOR_ORANGE); } else if (sgvLevel == 0) { mSgv.setTextColor(Color.BLACK); mDirection.setTextColor(Color.BLACK); @@ -94,7 +94,7 @@ public class Home extends BaseWatchFace { mTime.setTextColor(Color.BLACK); if (chart != null) { - highColor = Utils.COLOR_ORANGE; + highColor = ChartUtils.COLOR_ORANGE; midColor = Color.BLUE; lowColor = Color.RED; singleLine = false; diff --git a/wear/src/main/java/info/nightscout/androidaps/ListenerService.java b/wear/src/main/java/info/nightscout/androidaps/ListenerService.java index 2011bcb414..bd67a39762 100644 --- a/wear/src/main/java/info/nightscout/androidaps/ListenerService.java +++ b/wear/src/main/java/info/nightscout/androidaps/ListenerService.java @@ -26,6 +26,8 @@ public class ListenerService extends WearableListenerService implements GoogleAp private static final String WEARABLE_RESEND_PATH = "/nightscout_watch_data_resend"; private static final String OPEN_SETTINGS = "/openwearsettings"; private static final String NEW_STATUS_PATH = "/sendstatustowear"; + public static final String BASAL_DATA_PATH = "/nightscout_watch_basal"; + private static final String ACTION_RESEND = "com.dexdrip.stephenblack.nightwatch.RESEND_DATA"; private static final String ACTION_RESEND_BULK = "com.dexdrip.stephenblack.nightwatch.RESEND_BULK_DATA"; @@ -97,13 +99,19 @@ public class ListenerService extends WearableListenerService implements GoogleAp intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); - } else if (path.equals(NEW_STATUS_PATH)){ + } else if (path.equals(NEW_STATUS_PATH)) { dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Intent messageIntent = new Intent(); messageIntent.setAction(Intent.ACTION_SEND); messageIntent.putExtra("status", dataMap.toBundle()); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); - + } else if (path.equals(BASAL_DATA_PATH)){ + //TODO Adrian receive basals in Watchfaces + dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); + Intent messageIntent = new Intent(); + messageIntent.setAction(Intent.ACTION_SEND); + messageIntent.putExtra("basals", dataMap.toBundle()); + LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else { dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Intent messageIntent = new Intent(); diff --git a/wear/src/main/java/info/nightscout/androidaps/TempWatchData.java b/wear/src/main/java/info/nightscout/androidaps/TempWatchData.java new file mode 100644 index 0000000000..4b0854c3fc --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/TempWatchData.java @@ -0,0 +1,13 @@ +package info.nightscout.androidaps; + +/** + * Created by adrian on 17/11/16. + */ + +public class TempWatchData { + public long startTime; + public double startBasal; + public long endTime; + public double endBasal; + public double amount; +}