diff --git a/README-Combo.md b/README-Combo.md index 8e2677bc35..08ea75b271 100644 --- a/README-Combo.md +++ b/README-Combo.md @@ -141,6 +141,10 @@ Known issues: - AAPS might be unresponsive for 10-30s or so when starting and calculating sensitivity. AAPS might also be unresponsive when doing background work, e.g. after receiving a new glucose reading. +- Since the pump's date & time can't be updated automatically at this time, daylight saving changes + will cause an alert asking to update the pump clock. A usable workaround should be to disable + the automatic update of the phone's clock for the night and then enabling it again in the morning + when also updating the pump. Reporting bugs: - Note the precise time the problem occurred and describe the circumstances and steps that caused diff --git a/Steampunk_graphics_source_link.md b/Steampunk_graphics_source_link.md new file mode 100644 index 0000000000..a4de5ddcbf --- /dev/null +++ b/Steampunk_graphics_source_link.md @@ -0,0 +1,7 @@ +Follow this link to get the source PSD file for the Steampunk graphics. The file could not be included in the repository as it exceeds Github's 25 mb limit. + +Note, the source image size is 1600x1600. The image size should be reduced to 400x400 prior to export of final PNG. + +https://drive.google.com/drive/folders/1MrdgnQz3wOniDvRSMhAsqHBYb2WmE5i0 + +Graphics created by (Github): andrew-warrington \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index f0f5136937..b702897ba4 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -112,12 +112,16 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe runOnUiThread(new Runnable() { @Override public void run() { - recreate(); - try { // activity may be destroyed - setUpTabs(true); - } catch (IllegalStateException e) { - log.error("Unhandled exception", e); + if(ev.recreate) { + recreate(); + }else { + try { // activity may be destroyed + setUpTabs(true); + } catch (IllegalStateException e) { + log.error("Unhandled exception", e); + } } + boolean lockScreen = BuildConfig.NSCLIENTOLNY && SP.getBoolean("lockscreen", false); if (lockScreen) getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); diff --git a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java index 33a0483468..937c2ed53e 100644 --- a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.EditTextPreference; @@ -58,8 +59,9 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre if (key.equals("language")) { String lang = sharedPreferences.getString("language", "en"); LocaleHelper.setLocale(getApplicationContext(), lang); - recreate(); - MainApp.bus().post(new EventRefreshGui()); + MainApp.bus().post(new EventRefreshGui(true)); + //recreate() does not update language so better close settings + finish(); } if (key.equals("short_tabtitles")) { MainApp.bus().post(new EventRefreshGui()); diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java index 1dae34d2af..390ad8ea4f 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java +++ b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshGui.java @@ -4,4 +4,11 @@ package info.nightscout.androidaps.events; * Created by mike on 13.06.2016. */ public class EventRefreshGui extends Event { + public boolean recreate = false; + public EventRefreshGui(boolean recreate) { + this.recreate = recreate; + } + public EventRefreshGui(){ + this(false); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java index 40eab27a5e..af9440bff1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java @@ -533,7 +533,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick if (options.eventType == R.id.careportal_combobolus) { Double enteredInsulin = SafeParse.stringToDouble(editInsulin.getText()); data.put("enteredinsulin", enteredInsulin); - data.put("insulin", enteredInsulin * SafeParse.stringToDouble(editInsulin.getText()) / 100); + data.put("insulin", enteredInsulin * SafeParse.stringToDouble(editSplit.getText()) / 100); data.put("relative", enteredInsulin * (100 - SafeParse.stringToDouble(editSplit.getText())) / 100 / SafeParse.stringToDouble(editDuration.getText()) * 60); } } catch (JSONException e) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index d694b9d0a8..c09059ee30 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -11,6 +11,7 @@ import android.graphics.Paint; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; @@ -179,6 +180,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, Handler sLoopHandler = new Handler(); Runnable sRefreshLoop = null; + final Object updateSync = new Object(); + private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor(); private static ScheduledFuture scheduledUpdate = null; @@ -902,9 +905,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } @SuppressLint("SetTextI18n") - public void updateGUI(String from) { + public void updateGUI(final String from) { log.debug("updateGUI entered from: " + from); - Date updateGUIStart = new Date(); + final Date updateGUIStart = new Date(); if (getActivity() == null) return; @@ -926,7 +929,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, BgReading actualBG = DatabaseHelper.actualBg(); BgReading lastBG = DatabaseHelper.lastBg(); - PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); Profile profile = MainApp.getConfigBuilder().getProfile(); String units = profile.getUnits(); @@ -938,8 +941,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, return; } - double lowLine = SP.getDouble("low_mark", 0d); - double highLine = SP.getDouble("high_mark", 0d); + final double lowLine = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units)); + final double highLine = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units)); //Start with updating the BG as it is unaffected by loop. // **** BG value **** @@ -1143,16 +1146,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } - if (lowLine < 1) { - lowLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units); - } - if (highLine < 1) { - highLine = Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units); - } - // **** BG value **** if (lastBG == null) { //left this here as it seems you want to exit at this point if it is null... - return; } Integer flag = bgView.getPaintFlags(); @@ -1171,24 +1166,24 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, final IobTotal basalIob = MainApp.getConfigBuilder().getLastCalculationTempBasals().round(); if (shorttextmode) { - String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + " U"; + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U"; iobView.setText(iobtext); iobView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + " U\n" - + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + " U\n" - + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + " U\n"; + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U\n" + + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U\n" + + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U\n"; OKDialog.show(getActivity(), MainApp.sResources.getString(R.string.iob), iobtext, null); } }); } else if (MainApp.sResources.getBoolean(R.bool.isTablet)) { - String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + " U (" - + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + " U " - + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + " U)"; + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + + getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U " + + getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)"; iobView.setText(iobtext); } else { - String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + " U (" + String iobtext = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U (" + DecimalFormatter.to2Decimal(bolusIob.iob) + "/" + DecimalFormatter.to2Decimal(basalIob.basaliob) + ")"; iobView.setText(iobtext); @@ -1203,7 +1198,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, cobView.setText(cobText); } - boolean showPrediction = showPredictionView.isChecked() && finalLastRun != null && finalLastRun.constraintsProcessed.getClass().equals(DetermineBasalResultAMA.class); + final 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); getActivity().findViewById(R.id.overview_showprediction_label).setVisibility(View.VISIBLE); @@ -1247,105 +1242,121 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // ****** GRAPH ******* - // allign to hours - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(System.currentTimeMillis()); - calendar.set(Calendar.MILLISECOND, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.add(Calendar.HOUR, 1); + new Thread(new Runnable() { + @Override + public void run() { + // allign to hours + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(System.currentTimeMillis()); + calendar.set(Calendar.MILLISECOND, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.add(Calendar.HOUR, 1); - int hoursToFetch; - long toTime; - long fromTime; - long endTime; - if (showPrediction) { - int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000)); - predHours = Math.min(2, predHours); - predHours = Math.max(0, predHours); - hoursToFetch = rangeToDisplay - predHours; - toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific - fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; - endTime = toTime + predHours * 60 * 60 * 1000L; - } else { - hoursToFetch = rangeToDisplay; - toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific - fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; - endTime = toTime; - } + int hoursToFetch; + final long toTime; + final long fromTime; + final long endTime; + if (showPrediction) { + int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000)); + predHours = Math.min(2, predHours); + predHours = Math.max(0, predHours); + hoursToFetch = rangeToDisplay - predHours; + toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific + fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; + endTime = toTime + predHours * 60 * 60 * 1000L; + } else { + hoursToFetch = rangeToDisplay; + toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific + fromTime = toTime - hoursToFetch * 60 * 60 * 1000L; + endTime = toTime; + } - long now = System.currentTimeMillis(); + final long now = System.currentTimeMillis(); - // 2nd graph - // remove old data - iobGraph.getSeries().clear(); + // ------------------ 1st graph + Profiler.log(log, from + " - 1st graph - START", updateGUIStart); - GraphData secondGraphData = new GraphData(); + final GraphData graphData = new GraphData(bgGraph); - boolean useIobForScale = false; - boolean useCobForScale = false; - boolean useDevForScale = false; - boolean useRatioForScale = false; + // **** In range Area **** + graphData.addInRangeArea(fromTime, endTime, lowLine, highLine); - if (showIobView.isChecked()) { - useIobForScale = true; - } else if (showCobView.isChecked()) { - useCobForScale = true; - } else if (showDeviationsView.isChecked()) { - useDevForScale = true; - } else if (showRatiosView.isChecked()) { - useRatioForScale = true; - } + // **** BG **** + if (showPrediction) + graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed); + else + graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null); - if (showIobView.isChecked()) - secondGraphData.addIob(iobGraph, fromTime, now, useIobForScale, 1d); - if (showCobView.isChecked()) - secondGraphData.addCob(iobGraph, fromTime, now, useCobForScale, useCobForScale ? 1d : 0.5d); - if (showDeviationsView.isChecked()) - secondGraphData.addDeviations(iobGraph, fromTime, now, useDevForScale, 1d); - if (showRatiosView.isChecked()) - secondGraphData.addRatio(iobGraph, fromTime, now, useRatioForScale, 1d); + // set manual x bounds to have nice steps + graphData.formatAxis(fromTime, endTime); - if (showIobView.isChecked() || showCobView.isChecked() || showDeviationsView.isChecked() || showRatiosView.isChecked()) { - iobGraph.setVisibility(View.VISIBLE); - } else { - iobGraph.setVisibility(View.GONE); - } + // Treatments + graphData.addTreatments(fromTime, endTime); - // remove old data from graph - bgGraph.getSeries().clear(); + // add basal data + if (pump.getPumpDescription().isTempBasalCapable && showBasalsView.isChecked()) { + graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2d); + } - GraphData graphData = new GraphData(); + // **** NOW line **** + graphData.addNowLine(now); - // **** In range Area **** - graphData.addInRangeArea(bgGraph, fromTime, endTime, lowLine, highLine); + // ------------------ 2nd graph + Profiler.log(log, from + " - 2nd graph - START", updateGUIStart); - // **** BG **** - if (showPrediction) - graphData.addBgReadings(bgGraph, fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed); - else - graphData.addBgReadings(bgGraph, fromTime, toTime, lowLine, highLine, null); + final GraphData secondGraphData = new GraphData(iobGraph); - // set manual x bounds to have nice steps - graphData.formatAxis(bgGraph, fromTime, endTime); - secondGraphData.formatAxis(iobGraph, fromTime, endTime); + boolean useIobForScale = false; + boolean useCobForScale = false; + boolean useDevForScale = false; + boolean useRatioForScale = false; - // Treatments - graphData.addTreatments(bgGraph, fromTime, endTime); + if (showIobView.isChecked()) { + useIobForScale = true; + } else if (showCobView.isChecked()) { + useCobForScale = true; + } else if (showDeviationsView.isChecked()) { + useDevForScale = true; + } else if (showRatiosView.isChecked()) { + useRatioForScale = true; + } - // add basal data - if (pump.getPumpDescription().isTempBasalCapable && showBasalsView.isChecked()) { - graphData.addBasals(bgGraph, fromTime, now, lowLine / graphData.maxY / 1.2d); - } + if (showIobView.isChecked()) + secondGraphData.addIob(fromTime, now, useIobForScale, 1d); + if (showCobView.isChecked()) + secondGraphData.addCob(fromTime, now, useCobForScale, useCobForScale ? 1d : 0.5d); + if (showDeviationsView.isChecked()) + secondGraphData.addDeviations(fromTime, now, useDevForScale, 1d); + if (showRatiosView.isChecked()) + secondGraphData.addRatio(fromTime, now, useRatioForScale, 1d); - // **** NOW line **** - graphData.addNowLine(bgGraph, now); - secondGraphData.addNowLine(iobGraph, now); + // **** NOW line **** + // set manual x bounds to have nice steps + secondGraphData.formatAxis(fromTime, endTime); + secondGraphData.addNowLine(now); - // finaly enforce drawing of graphs - bgGraph.onDataChanged(false, false); - iobGraph.onDataChanged(false, false); + // do GUI update + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (showIobView.isChecked() || showCobView.isChecked() || showDeviationsView.isChecked() || showRatiosView.isChecked()) { + iobGraph.setVisibility(View.VISIBLE); + } else { + iobGraph.setVisibility(View.GONE); + } + // finally enforce drawing of graphs + graphData.performUpdate(); + secondGraphData.performUpdate(); + Profiler.log(log, from + " - onDataChanged", updateGUIStart); + } + }); + } + } + }).start(); Profiler.log(log, from, updateGUIStart); } @@ -1431,6 +1442,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } } + } void updateNotifications() { 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 99f53ad2ef..e76714c5b2 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 @@ -45,15 +45,18 @@ import info.nightscout.utils.Round; public class GraphData { - public GraphData() { - units = MainApp.getConfigBuilder().getProfileUnits(); - } - + private GraphView graph; public double maxY = 0; private List bgReadingsArray; private String units; + private List series = new ArrayList<>(); - public void addBgReadings(GraphView bgGraph, long fromTime, long toTime, double lowLine, double highLine, DetermineBasalResultAMA amaResult) { + public GraphData(GraphView graph) { + units = MainApp.getConfigBuilder().getProfileUnits(); + this.graph = graph; + } + + public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, DetermineBasalResultAMA amaResult) { double maxBgValue = 0d; bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true); List bgListArray = new ArrayList<>(); @@ -81,20 +84,18 @@ public class GraphData { DataPointWithLabelInterface[] bg = new DataPointWithLabelInterface[bgListArray.size()]; bg = bgListArray.toArray(bg); - if (bg.length > 0) { - addSeriesWithoutInvalidate(bgGraph, new PointsWithLabelGraphSeries<>(bg)); - } maxY = maxBgValue; // set manual y bounds to have nice steps - bgGraph.getViewport().setMaxY(maxY); - bgGraph.getViewport().setMinY(0); - bgGraph.getViewport().setYAxisBoundsManual(true); - bgGraph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines); + graph.getViewport().setMaxY(maxY); + graph.getViewport().setMinY(0); + graph.getViewport().setYAxisBoundsManual(true); + graph.getGridLabelRenderer().setNumVerticalLabels(numOfVertLines); + addSeries(new PointsWithLabelGraphSeries<>(bg)); } - public void addInRangeArea(GraphView bgGraph, long fromTime, long toTime, double lowLine, double highLine) { + public void addInRangeArea(long fromTime, long toTime, double lowLine, double highLine) { AreaGraphSeries inRangeAreaSeries; DoubleDataPoint[] inRangeAreaDataPoints = new DoubleDataPoint[]{ @@ -102,14 +103,15 @@ public class GraphData { new DoubleDataPoint(toTime, lowLine, highLine) }; inRangeAreaSeries = new AreaGraphSeries<>(inRangeAreaDataPoints); - addSeriesWithoutInvalidate(bgGraph, inRangeAreaSeries); inRangeAreaSeries.setColor(0); inRangeAreaSeries.setDrawBackground(true); inRangeAreaSeries.setBackgroundColor(MainApp.sResources.getColor(R.color.inrangebackground)); + + addSeries(inRangeAreaSeries); } // scale in % of vertical size (like 0.3) - public void addBasals(GraphView bgGraph, long fromTime, long toTime, double scale) { + public void addBasals(long fromTime, long toTime, double scale) { LineGraphSeries basalsLineSeries; LineGraphSeries absoluteBasalsLineSeries; LineGraphSeries baseBasalsSeries; @@ -194,7 +196,7 @@ public class GraphData { basalsLineSeries = new LineGraphSeries<>(basalLine); Paint paint = new Paint(); paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(MainApp.instance().getApplicationContext().getResources().getDisplayMetrics().scaledDensity*2); + paint.setStrokeWidth(MainApp.instance().getApplicationContext().getResources().getDisplayMetrics().scaledDensity * 2); paint.setPathEffect(new DashPathEffect(new float[]{2, 4}, 0)); paint.setColor(MainApp.sResources.getColor(R.color.basal)); basalsLineSeries.setCustomPaint(paint); @@ -204,19 +206,19 @@ public class GraphData { absoluteBasalsLineSeries = new LineGraphSeries<>(absoluteBasalLine); Paint absolutePaint = new Paint(); absolutePaint.setStyle(Paint.Style.STROKE); - absolutePaint.setStrokeWidth(MainApp.instance().getApplicationContext().getResources().getDisplayMetrics().scaledDensity*2); + absolutePaint.setStrokeWidth(MainApp.instance().getApplicationContext().getResources().getDisplayMetrics().scaledDensity * 2); absolutePaint.setColor(MainApp.sResources.getColor(R.color.basal)); absoluteBasalsLineSeries.setCustomPaint(absolutePaint); basalScale.setMultiplier(maxY * scale / maxBasalValueFound); - addSeriesWithoutInvalidate(bgGraph, baseBasalsSeries); - addSeriesWithoutInvalidate(bgGraph, tempBasalsSeries); - addSeriesWithoutInvalidate(bgGraph, basalsLineSeries); - addSeriesWithoutInvalidate(bgGraph, absoluteBasalsLineSeries); + addSeries(baseBasalsSeries); + addSeries(tempBasalsSeries); + addSeries(basalsLineSeries); + addSeries(absoluteBasalsLineSeries); } - public void addTreatments(GraphView bgGraph, long fromTime, long endTime) { + public void addTreatments(long fromTime, long endTime) { List filteredTreatments = new ArrayList<>(); List treatments = MainApp.getConfigBuilder().getTreatmentsFromHistory(); @@ -262,9 +264,7 @@ public class GraphData { DataPointWithLabelInterface[] treatmentsArray = new DataPointWithLabelInterface[filteredTreatments.size()]; treatmentsArray = filteredTreatments.toArray(treatmentsArray); - if (treatmentsArray.length > 0) { - addSeriesWithoutInvalidate(bgGraph, new PointsWithLabelGraphSeries<>(treatmentsArray)); - } + addSeries(new PointsWithLabelGraphSeries<>(treatmentsArray)); } double getNearestBg(long date) { @@ -279,7 +279,7 @@ public class GraphData { } // scale in % of vertical size (like 0.3) - public void addIob(GraphView graph, long fromTime, long toTime, boolean useForScale, double scale) { + public void addIob(long fromTime, long toTime, boolean useForScale, double scale) { FixedLineGraphSeries iobSeries; List iobArray = new ArrayList<>(); Double maxIobValueFound = 0d; @@ -310,11 +310,11 @@ public class GraphData { iobScale.setMultiplier(maxY * scale / maxIobValueFound); - addSeriesWithoutInvalidate(graph, iobSeries); + addSeries(iobSeries); } // scale in % of vertical size (like 0.3) - public void addCob(GraphView graph, long fromTime, long toTime, boolean useForScale, double scale) { + public void addCob(long fromTime, long toTime, boolean useForScale, double scale) { FixedLineGraphSeries cobSeries; List cobArray = new ArrayList<>(); Double maxCobValueFound = 0d; @@ -349,11 +349,11 @@ public class GraphData { cobScale.setMultiplier(maxY * scale / maxCobValueFound); - addSeriesWithoutInvalidate(graph, cobSeries); + addSeries(cobSeries); } // scale in % of vertical size (like 0.3) - public void addDeviations(GraphView graph, long fromTime, long toTime, boolean useForScale, double scale) { + public void addDeviations(long fromTime, long toTime, boolean useForScale, double scale) { class DeviationDataPoint extends ScaledDataPoint { public int color; @@ -396,11 +396,11 @@ public class GraphData { devScale.setMultiplier(maxY * scale / maxDevValueFound); - addSeriesWithoutInvalidate(graph, devSeries); + addSeries(devSeries); } // scale in % of vertical size (like 0.3) - public void addRatio(GraphView graph, long fromTime, long toTime, boolean useForScale, double scale) { + public void addRatio(long fromTime, long toTime, boolean useForScale, double scale) { LineGraphSeries ratioSeries; List ratioArray = new ArrayList<>(); Double maxRatioValueFound = 0d; @@ -426,11 +426,11 @@ public class GraphData { ratioScale.setMultiplier(maxY * scale / maxRatioValueFound); - addSeriesWithoutInvalidate(graph, ratioSeries); + addSeries(ratioSeries); } // scale in % of vertical size (like 0.3) - public void addNowLine(GraphView graph, long now) { + public void addNowLine(long now) { LineGraphSeries seriesNow; DataPoint[] nowPoints = new DataPoint[]{ new DataPoint(now, 0), @@ -447,10 +447,10 @@ public class GraphData { paint.setColor(Color.WHITE); seriesNow.setCustomPaint(paint); - addSeriesWithoutInvalidate(graph, seriesNow); + addSeries(seriesNow); } - public void formatAxis(GraphView graph, long fromTime, long endTime) { + public void formatAxis(long fromTime, long endTime) { graph.getViewport().setMaxX(endTime); graph.getViewport().setMinX(fromTime); graph.getViewport().setXAxisBoundsManual(true); @@ -458,11 +458,23 @@ public class GraphData { graph.getGridLabelRenderer().setNumHorizontalLabels(7); // only 7 because of the space } - private void addSeriesWithoutInvalidate(GraphView bgGraph, Series s) { - if (!s.isEmpty()) { - s.onGraphViewAttached(bgGraph); - bgGraph.getSeries().add(s); - } + private void addSeries(Series s) { + series.add(s); } + public void performUpdate() { + // clear old data + graph.getSeries().clear(); + + // add precalculated series + for (Series s: series) { + if (!s.isEmpty()) { + s.onGraphViewAttached(graph); + graph.getSeries().add(s); + } + } + + // draw it + graph.onDataChanged(false, false); + } } 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 73b6692904..91045ba4d6 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 @@ -243,6 +243,7 @@ public class WatchUpdaterService extends WearableListenerService implements DataMap dataMap = new DataMap(); dataMap.putString("sgvString", lastBG.valueToUnitsToString(units)); + dataMap.putString("glucoseUnits", units); dataMap.putLong("timestamp", lastBG.date); if (glucoseStatus == null) { dataMap.putString("slopeArrow", ""); @@ -253,7 +254,6 @@ public class WatchUpdaterService extends WearableListenerService implements dataMap.putString("delta", deltastring(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)); dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units)); } - dataMap.putLong("sgvLevel", sgvLevel); dataMap.putDouble("sgvDouble", lastBG.value); dataMap.putDouble("high", highLine); diff --git a/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java b/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java index 8dff2aec93..b5ed76af02 100644 --- a/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/tabs/TabPageAdapter.java @@ -9,8 +9,12 @@ import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.view.ViewGroup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; +import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.interfaces.PluginBase; /** @@ -22,6 +26,8 @@ public class TabPageAdapter extends FragmentStatePagerAdapter { Context context; + private static Logger log = LoggerFactory.getLogger(TabPageAdapter.class); + public TabPageAdapter(FragmentManager fm, Context context) { super(fm); this.context = context; @@ -40,6 +46,8 @@ public class TabPageAdapter extends FragmentStatePagerAdapter { super.finishUpdate(container); } catch (NullPointerException nullPointerException){ System.out.println("Catch the NullPointerException in FragmentStatePagerAdapter.finishUpdate"); + } catch (IllegalStateException e){ + log.error(e.getMessage()); } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index eea3c9790c..8edea19afe 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -97,11 +97,10 @@ VIRTUELLE PUMPE SQL Error Verlängerter Bolus - TBR Sichtbar + Basis-Basalrate GESAMT Nicht unterstützte Version des Nightscout-Clients - Basis Basalrate BZ Bolus-IOB Kohlenhydrate @@ -306,7 +305,7 @@ SP PROF HOME - OBJ + ZIEL OAPS LOOP LP @@ -333,11 +332,11 @@ Bluetooth-Status Kumulative TDD Datum - Exponentiell Gewichtete TDD + Exponentiell gewichtete TDD Veraltete Daten, bitte klicke auf \"Reload\" xds - xDrip Statuszeile (Uhr) - xDrip Status (Uhr) + xDrip+ Statuszeile (Uhr) + xDrip+ Status (Uhr) xDrip+ nicht installiert Zeige BGI Füge BGI zur Statuszeile hinzu @@ -450,7 +449,7 @@ Logs anzeigen nicht erfolgreich - bitte Telefon prüfen Nicht verfügbar - NSClient hat keine Schreibrechte. Falscher API-Key? + Nightscout-Client hat keine Schreibrechte. Falscher API-Key? Alarm-Optionen Aktiviere Broadcasts für andere Apps (z. B. xDrip+). Aktiviere lokale Broadcasts. @@ -603,7 +602,7 @@ Fein-Einstellung des Closed-Loops, Erhöhen von max IOB über 0 und langsames Heruntersetzen des Zielbereichs Eine Woche erfolgreiches Loopen am Tag mit regelmäßiger Kohlenhydrat-Eingabe Passe, falls notwendig, Basal und Faktoren an und aktiviere dann die Autosense-Funktion - Aktiviere zusätzliche Funktionen wie z. B. den Mahlzeitenassistent + Aktiviere zusätzliche Funktionen, wie z. B. den Mahlzeitenassistent Stark veraltete Daten Stark veraltete Daten seit [Min.] Dutch @@ -671,8 +670,8 @@ Alarm, wenn keine Glukose-Daten empfangen werden Alarm, wenn die Pumpe nicht erreichbar ist Pumpe ist nicht erreichbar Grenze [Min.] + Aktualisieren TZ - Bitte starte dein Telefon neu oder starte AndroidAPS in den System-Einstellungen neu. Andernfalls wird AndroidAPS nicht protokolliert (wichtig zum Nachverfolgen und Verifizieren, dass der Algorithmus korrekt funktioniert) TBR Pumpen-Speicher Aktiviere die SuperBolus-Funktion im Wizard. Nicht aktivieren, wenn du nicht weißt, welche Auswirkungen dieser Bolus hat! ES KANN ZU EINER ÜBERDOSIERUNG AN INSULIN KOMMEN! @@ -701,6 +700,66 @@ Wähle in xDrip+ 640g/Eversense als Daten-Quelle Nightscout-Client BZ Basal-Wert wurde durch den kleinst möglichen Wert ersetzt + APS ausgewählt + Loop aktiviert + Nightscout-Client hat Schreibrechte + Maximales IOB richtig gesetzt + Closed mode aktiviert + Aktiviere zusätzliche Funktionen wie z. B. den SMB + BT Watchdog + DexcomG5 App (patched) + Aktivität + %d%% (%d Min. verbleibend) + Keine Verbindung zur Pumpe seit %d Min. + Bolusabgabe gestoppt + Bolusabgabe wird abgebrochen + Fehlerprotokol + Status + Keine Verbindung zur Pumpe + Durch Benutzer gestoppt + Wegen Fehler gestoppt + Normaler Betrieb + TDDS + Bolusabgabe wird vorbereitet + TBR wird abgebrochen + TBR wird gesetzt (%d%% / %d Min.) + Bolus (%.1f IE) wird abgegeben + Bitte starte dein Telefon neu oder starte AndroidAPS in den System-Einstellungen neu. Andernfalls wird AndroidAPS nicht protokolliert (wichtig zum Nachverfolgen und Verifizieren, dass der Algorithmus korrekt funktioniert) + TBR + %.1f IE (%s, %s) + Nutze System-Benachrichtigungen für Alarme + Ein gleich großer Bolus wurde in der letzten Minute angefordert. Dies ist nicht zulässig, um ungewollte Doppelboli zu verhindern und vor eventuellen Bugs zu schützen. + Historie wird gelesen + Basalratenprofil wird aktualisiert + Verbindung wird wieder hergestellt + Der abgegebene Bolus konnte nicht bestätigt werden. Bitte prüfe auf der Pumpe, ob ein Bolus abgegeben wurde und erstelle einen Eintrag im Careportal falls nötig. + Die Bolusabgabe ist fehlgeschlagen: Es wurde scheinbar kein Bolus abgegeben. Bitte prüfe auf der Pumpe, ob ein Bolus abgegeben wurde. Um doppelte Boli durch Programmfehler zu vermeiden, werden Boli nicht automatisch wiederholt. + Wegen eines Fehlers wurden nur %.2f IE von den angeforderten %.2f IE abgegeben. Bitte prüfe den abgegebenen Bolus auf der Pumpe. + Historie + Status wird aktualisiert + Die Pumpe wird initialisiert + Jetzt + Nie + Der Alarm \"TBR ABBRUCH\" wurde bestätigt + Warnung + Leer + Niedrig + Normal + Durchschnitt: %3.1f IE + Maximum: %3.1f IE + Minimum: %3.1f IE + Diese Aktion wird von der Pumpe nicht unterstützt + Alarme + Die Batterie in der Pumpe ist fast leer + Das Reservoir in der Pumpe ist fast leer + Die Pumpe zeigt einen Fehler an E%d: %s + Unsichere Verwendung: In der Pumpe ist nicht das erste Basalratenprofil gewählt. Der Loop wird deaktiviert bis dies korrigiert ist. + Unsichere Verwendung: Ein erweiterter oder Multiwave-Bolus ist aktiv. Der Loop wird für die nächsten 6 Stunden kein zusätzliches Insulin abgeben. + Um die Fehlerhistorie der Pumpe zu lesen, drücke lange auf ALARME.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe, der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst eine Taste gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. + Bitte aktualisiere die Uhrzeit der Pumpe + Um die TDD-Statistik der Pumpe zu lesen, drücken Sie den TDDS Knopf lange.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst ein Konpf gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. + Dies wird den gesamten Speicher und den Status der Pumpe auslesen sowie alle Einträge in „Meine Daten“ und die Basalrate. Boli und TBR werden unter Behandlungen gespeichert, sofern sie nicht bereits vorhanden sind. Dies kann zu doppelten Einträgen führen, wenn die Uhrzeit der Pumpe abweicht. Das Auslesen des Speichers ist normaler Weise für das Loopen unnötig und nur für besondere Umstände vorgesehen. Wenn Du es dennoch tun willst, drücke noch einmal länger den Button. ACHTUNG: Dies kann einen Fehler auslösen, der dazu führt, dass die Pumpe keine Verbindungsversuche mehr akzeptiert. Erst die Betätigung einer Taste an der Pumpe beendet diesen Zustand. Nach Möglichkeit sollte daher das Auslesen vermieden werden. + Möchtest Du wirklich den gesamten Speicher der Pumpe auslesen und die möglichen Konsequenzen des Vorgangs tragen? Ja Nein BZ Berechnung @@ -719,64 +778,4 @@ Standarwert: 2\nBolus snooze (\"Bolus-Schlummer\") bremst den Loop nach einem Mahleiten-Bolus, damit dieser nicht mit niedrigen TBR reagiert, wenn Du gerade gegessen hast. Beispiel: Der Standardwert 2 bewirkt, dass bei einem 3 Stunden DIA der Bolus snooze während 1.5 Stunden nach dem Bolus linear ausläuft (3 h Dia / 2 = 1.5 h Bolus snooze). Standardwert: 3.0\nDies ist eine Einstellung für die Standard-Kohlenhydrat-Absorptionswirkung pro 5 Minuten. Der Standardwert ist 3mg/dl/5min. Dies wirkt sich darauf aus, wie schnell der COB-Wert fällt und wieviel KH-Absorption bei der Berechnung des vorhergesagten BZ angenommen wird, wenn der BZ stärker als erwartet fällt oder nicht so stark wie erwartet steigt. Achtung! Normalerweise musst Du diese Werte nicht ändern. Bitte KLICKE HIER und LESE den Text. Verändere Werte erst, wenn Du den Inhalt des Textes verstanden hast. - APS ausgewählt - Loop aktiviert - Nightscout-Client hat Schreibrechte - Maximales IOB richtig gesetzt - Closed mode aktiviert - Letzte Verbindung - Basis-Basalrate - Reservoir - Letzter Bolus: - Aktiviere zusätzliche Funktionen wie z. B. den SMB - BT Watchdog - DexcomG5 App (patched) - Aktualisieren - Aktivität - %d%% (%d Min. verbleibend) - Keine Verbindung zur Pumpe seit %d min - Bolusabgabe gestopped - Bolusabgabe wird abgebrochen - Fehlerprotokol - Status - Keine Verbindung zur Pumpe - Durch Benutzer gestoppt - Wegen Fehler gestoppt - Normaler Betrieb - TDDS - Bolusabgabe wird vorbereitet - TBR wird abgebrochen - TBR wird gesetzt (%d%% / %d min) - Bolus (%.1f E) wird abgegeben - Historik wird gelesen - Basalratenprofil wird aktualisiert - Verbindung wurde unterbrochen, es wird versucht fortzusetzen - Der abgegebene Bolus konnte nicht bestätigt werden. Bitte prüfen Sie auf der Pumpe ob ein Bolus abgegeben wurde und erstellen Sie einen Eintrag im Careportal Reiter falls nötig. - Die Bolusabgabe ist fehlgeschlagen, es wurde scheinbar kein Bolus abgegeben. Bitte prüfen Sie auf der Pumpe ob ein Bolus abgegeben wurde. Um dopplte Boli durch Programmfehler zu vermeiden werden Boli nicht automatisch erneut versucht. - Wegen eines Fehlers wurden nur %.2f IE von den angeforderten %.2f IE abgegeben. Bitte prüfen Sie den abgegeben Bolus auf der Pumpe. - Historik - Status wird aktualisiert - Die Pumpe wird initialisiert - Jetzt - Nie - Ein TBR ABGEBROCHEN Alarm wurde bestätigt - Warnung - Leer - Niedrig - Normal - Durchschnitt: %3.1f IE - Maximum: %3.1f IE - Minimum: %3.1f IE - Diese Aktion wird von der Pumpe nicht unterstützt - Alarme - Die Batterie in der Pumpe ist fast leer - Das Reservoir in der Pumpe ist fast leer - Die Pumpe zeigt einen Fehler an E%d: %s - Unsichere Verwendung: die Pumpe hat nicht das erste Basalratenprofil als aktiv gesetzt. Der Loop wird deaktiviert bis dies korrigiert ist. - Unsichere Verwendung: ein erweiterter- oder Multiwave-Bolus ist aktiv. Der Loop wird für die nächsten 6 Stunden kein zusätzliches Insulin abgeben. - Um die Fehlerhistorik der Pumpe zu lesen, drücken Sie den ALARME Knopf lange.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst ein Konpf gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. - Bitte aktualisieren Sie die Uhr auf der Pumpe - Um die TDD-Statistik der Pumpe zu lesen, drücken Sie den TDDS Knopf lange.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst ein Konpf gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. - Sind Sie sich sicher, dass Sie diese Aktion ausführen möchen und verstehen Sie die Konsequenzen die sich daraus ergeben? - Diese Aktion wird die gesamte Historik und die Basalrate aus der Pumpe auslesen. Boli und temporäre Basalrate werden zu den Behandlungen hinzugefügt wenn diese noch nicht vorhanden sind. Dies kann zu doppelten Einträge und somit zu falschen IOB-Werten führen, da die Uhr der Pumpe ungenau ist. Diese Aktion sollte NIE durchgeführt werden wenn die Pumpe im Loop verwendet wird. Wenn Sie diese Aktion trotzdem durchführen möchten, drücken Sie lange erneut auf den diesen Knopf.\nWARNUNG: Es gibt einen bekannten Fehler in der Pumpe der dazu führt, dass die Pumpe nach dieser Aktion erst wieder Verbindungen annimmt, wenn auf der Pumpe selbst ein Konpf gedrückt wird. Aus diesem Grund sollte diese Aktion nicht durchgeführt werden. diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index e6c15d799d..32cf7a5d1d 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -111,6 +111,25 @@ + + + + + + + + + + + start_time) { - lines.add(tempValuesLine(twd, (float) minChart, factor, false, highlight?3:2)); + lines.add(tempValuesLine(twd, (float) minChart, factor, false, highlight?(pointSize+1):pointSize)); if(highlight){ lines.add(tempValuesLine(twd, (float) minChart, factor, true, 1)); } diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/Steampunk.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/Steampunk.java new file mode 100644 index 0000000000..06f50edfb0 --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/Steampunk.java @@ -0,0 +1,243 @@ +package info.nightscout.androidaps.watchfaces; + +import android.content.Intent; +import android.support.v4.content.ContextCompat; +import android.support.wearable.watchface.WatchFaceStyle; +import android.view.LayoutInflater; +import android.view.animation.Animation; +import android.view.animation.LinearInterpolator; +import android.view.animation.RotateAnimation; + +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.interaction.menus.MainMenuActivity; + +/** + * Created by andrew-warrington on 01/12/2017. + */ + +public class Steampunk extends BaseWatchFace { + + private long chartTapTime = 0; + private long mainMenuTapTime = 0; + private float lastEndDegrees = 0f; + private float deltaRotationAngle = 0f; + + @Override + public void onCreate() { + forceSquareCanvas = true; + super.onCreate(); + LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); + layoutView = inflater.inflate(R.layout.activity_steampunk, null); + performViewSetup(); + } + + @Override + protected void onTapCommand(int tapType, int x, int y, long eventTime) { + + if (tapType == TAP_TYPE_TAP&& + x >= mChartTap.getLeft() && + x <= mChartTap.getRight()&& + y >= mChartTap.getTop() && + y <= mChartTap.getBottom()){ + if (eventTime - chartTapTime < 800){ + changeChartTimeframe(); + } + chartTapTime = eventTime; + + } else if (tapType == TAP_TYPE_TAP&& + x >= mMainMenuTap.getLeft() && + x <= mMainMenuTap.getRight()&& + y >= mMainMenuTap.getTop() && + y <= mMainMenuTap.getBottom()){ + if (eventTime - mainMenuTapTime < 800){ + Intent intent = new Intent(this, MainMenuActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + mainMenuTapTime = eventTime; + } + } + + @Override + protected WatchFaceStyle getWatchFaceStyle() { + return new WatchFaceStyle.Builder(this).setAcceptsTapEvents(true).build(); + } + + protected void setColorDark() { + + if (mLinearLayout2 != null) { + if (ageLevel() <= 0) { + mLinearLayout2.setBackgroundResource(R.drawable.redline); + mTimestamp.setTextColor(getResources().getColor(R.color.red_600)); + } else { + mLinearLayout2.setBackgroundResource(0); + mTimestamp.setTextColor(getResources().getColor(R.color.black_86p)); + } + } + + if (mLoop != null) { + if (loopLevel == 0) { + mLoop.setTextColor(getResources().getColor(R.color.red_600)); + } else { + mLoop.setTextColor(getResources().getColor(R.color.black_86p)); + } + } + + if (!sSgv.equals("---")) { + + float rotationAngle = 0f; //by default, show ? on the dial (? is at 0 degrees on the dial) + + if (!sUnits.equals("-")) { + + //ensure the glucose dial is the correct units + if (sUnits.equals("mmol")) { + mGlucoseDial.setImageResource(R.drawable.steampunk_dial_mmol); + } else { + mGlucoseDial.setImageResource(R.drawable.steampunk_dial_mgdl); + } + + //convert the Sgv to degrees of rotation + if (sUnits.equals("mmol")) { + rotationAngle = Float.valueOf(sSgv) * 18f; //convert to mg/dL, which is equivalent to degrees + } else { + rotationAngle = Float.valueOf(sSgv); //if glucose a value is received, use it to determine the amount of rotation of the dial. + } + + } + + if (rotationAngle > 330) rotationAngle = 330; //if the glucose value is higher than 330 then show "HIGH" on the dial. ("HIGH" is at 330 degrees on the dial) + if (rotationAngle != 0 && rotationAngle < 30) rotationAngle = 30; //if the glucose value is lower than 30 show "LOW" on the dial. ("LOW" is at 30 degrees on the dial) + + //rotate glucose dial + RotateAnimation rotate = new RotateAnimation( + lastEndDegrees, rotationAngle - lastEndDegrees, + Animation.RELATIVE_TO_SELF, 0.5f, + Animation.RELATIVE_TO_SELF, 0.5f); + rotate.setFillAfter(true); + rotate.setInterpolator(new LinearInterpolator()); + rotate.setDuration(1); + mGlucoseDial.startAnimation(rotate); + lastEndDegrees = rotationAngle; //store the final angle as a starting point for the next rotation. + } + + //set the delta gauge and rotate the delta pointer + float deltaIsNegative = 1f; //by default go clockwise + if (!sAvgDelta.equals("--")) { //if a legitimate delta value is received, then... + if (sAvgDelta.substring(0,1).equals("-")) deltaIsNegative = -1f; //if the delta is negative, go counter-clockwise + + //ensure the delta gauge is the right units and granularity + if (!sUnits.equals("-")) { + if (sUnits.equals("mmol")) { + if (sharedPrefs.getString("delta_granularity", "2").equals("1")) { //low + mLinearLayout.setBackgroundResource(R.drawable.steampunk_gauge_mmol_10); + deltaRotationAngle = (Float.valueOf(sAvgDelta.substring(1)) * 30f); //get rid of the sign so it can be converted to float. + } + if (sharedPrefs.getString("delta_granularity", "2").equals("2")) { //medium + mLinearLayout.setBackgroundResource(R.drawable.steampunk_gauge_mmol_05); + deltaRotationAngle = (Float.valueOf(sAvgDelta.substring(1)) * 60f); //get rid of the sign so it can be converted to float. + } + if (sharedPrefs.getString("delta_granularity", "2").equals("3")) { //high + mLinearLayout.setBackgroundResource(R.drawable.steampunk_gauge_mmol_03); + deltaRotationAngle = (Float.valueOf(sAvgDelta.substring(1)) * 100f); //get rid of the sign so it can be converted to float. + } + } else { + if (sharedPrefs.getString("delta_granularity", "2").equals("1")) { //low + mLinearLayout.setBackgroundResource(R.drawable.steampunk_gauge_mgdl_20); + deltaRotationAngle = (Float.valueOf(sAvgDelta.substring(1)) * 1.5f); //get rid of the sign so it can be converted to float. + } + if (sharedPrefs.getString("delta_granularity", "2").equals("2")) { //medium + mLinearLayout.setBackgroundResource(R.drawable.steampunk_gauge_mgdl_10); + deltaRotationAngle = (Float.valueOf(sAvgDelta.substring(1)) * 3f); //get rid of the sign so it can be converted to float. + } + if (sharedPrefs.getString("delta_granularity", "2").equals("3")) { //high + mLinearLayout.setBackgroundResource(R.drawable.steampunk_gauge_mgdl_5); + deltaRotationAngle = (Float.valueOf(sAvgDelta.substring(1)) * 6f); //get rid of the sign so it can be converted to float. + } + } + } + if (deltaRotationAngle > 40) deltaRotationAngle = 40f; + mDeltaGauge.setRotation(deltaRotationAngle * deltaIsNegative); + } + + //rotate the minute hand. + mMinuteHand.setRotation(Float.valueOf(sMinute) * 6f); + + //rotate the hour hand. + mHourHand.setRotation((Float.valueOf(sHour) * 30f) + (Float.valueOf(sMinute) * 0.5f)); + + setTextSizes(); + + if (mLoop != null) { + mLoop.setBackgroundResource(0); + } + + if (chart != null) { + highColor = ContextCompat.getColor(getApplicationContext(), R.color.black); + lowColor = ContextCompat.getColor(getApplicationContext(), R.color.black); + midColor = ContextCompat.getColor(getApplicationContext(), R.color.black); + gridColor = ContextCompat.getColor(getApplicationContext(), R.color.grey_steampunk); + basalBackgroundColor = ContextCompat.getColor(getApplicationContext(), R.color.basal_dark); + basalCenterColor = ContextCompat.getColor(getApplicationContext(), R.color.basal_dark); + pointSize = 1; + setupCharts(); + } + + invalidate(); + + } + + protected void setColorLowRes() { + setColorDark(); + } + + protected void setColorBright() { + setColorDark(); + } + + protected void setTextSizes() { + + float fontSmall = 10f; + float fontMedium = 11f; + float fontLarge = 12f; + + if (bIsRound) { + fontSmall = 11f; + fontMedium = 12f; + fontLarge = 13f; + } + + //top row. large font unless text too big (i.e. detailedIOB) + mCOB2.setTextSize(fontLarge); + mBasalRate.setTextSize(fontLarge); + if (sIOB2.length() < 7) { + mIOB2.setTextSize(fontLarge); + } else { + mIOB2.setTextSize(fontSmall); + } + + //bottom row. font medium unless text too long (i.e. longer than 9' timestamp) + if (mTimestamp.getText().length() < 3 || mLoop.getText().length() < 3) { //always resize these fields together, for symmetry. + mTimestamp.setTextSize(fontMedium); + mLoop.setTextSize(fontMedium); + } else { + mTimestamp.setTextSize(fontSmall); + mLoop.setTextSize(fontSmall); + } + + //if both batteries are shown, make them smaller. + if (sharedPrefs.getBoolean("show_uploader_battery", true) && sharedPrefs.getBoolean("show_rig_battery", false)) { + mUploaderBattery.setTextSize(fontSmall); + mRigBattery.setTextSize(fontSmall); + } else { + mUploaderBattery.setTextSize(fontMedium); + mRigBattery.setTextSize(fontMedium); + } + } + + private void changeChartTimeframe() { + int timeframe = Integer.parseInt(sharedPrefs.getString("chart_timeframe", "3")); + timeframe = (timeframe%5) + 1; + sharedPrefs.edit().putString("chart_timeframe", "" + timeframe).commit(); + } + +} \ No newline at end of file diff --git a/wear/src/main/res/drawable/redline.png b/wear/src/main/res/drawable/redline.png new file mode 100644 index 0000000000..37d8859709 Binary files /dev/null and b/wear/src/main/res/drawable/redline.png differ diff --git a/wear/src/main/res/drawable/steampunk_cover_plate.png b/wear/src/main/res/drawable/steampunk_cover_plate.png new file mode 100644 index 0000000000..f6d6c0c961 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_cover_plate.png differ diff --git a/wear/src/main/res/drawable/steampunk_dial_mgdl.png b/wear/src/main/res/drawable/steampunk_dial_mgdl.png new file mode 100644 index 0000000000..e6315b1746 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_dial_mgdl.png differ diff --git a/wear/src/main/res/drawable/steampunk_dial_mmol.png b/wear/src/main/res/drawable/steampunk_dial_mmol.png new file mode 100644 index 0000000000..17325212c3 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_dial_mmol.png differ diff --git a/wear/src/main/res/drawable/steampunk_gauge_mgdl_10.png b/wear/src/main/res/drawable/steampunk_gauge_mgdl_10.png new file mode 100644 index 0000000000..6d268bebd7 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_gauge_mgdl_10.png differ diff --git a/wear/src/main/res/drawable/steampunk_gauge_mgdl_20.png b/wear/src/main/res/drawable/steampunk_gauge_mgdl_20.png new file mode 100644 index 0000000000..a509d7b308 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_gauge_mgdl_20.png differ diff --git a/wear/src/main/res/drawable/steampunk_gauge_mgdl_5.png b/wear/src/main/res/drawable/steampunk_gauge_mgdl_5.png new file mode 100644 index 0000000000..9288c4e5ab Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_gauge_mgdl_5.png differ diff --git a/wear/src/main/res/drawable/steampunk_gauge_mmol_03.png b/wear/src/main/res/drawable/steampunk_gauge_mmol_03.png new file mode 100644 index 0000000000..18b8d0bf4e Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_gauge_mmol_03.png differ diff --git a/wear/src/main/res/drawable/steampunk_gauge_mmol_05.png b/wear/src/main/res/drawable/steampunk_gauge_mmol_05.png new file mode 100644 index 0000000000..07a48e8aac Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_gauge_mmol_05.png differ diff --git a/wear/src/main/res/drawable/steampunk_gauge_mmol_10.png b/wear/src/main/res/drawable/steampunk_gauge_mmol_10.png new file mode 100644 index 0000000000..55f5e59b5b Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_gauge_mmol_10.png differ diff --git a/wear/src/main/res/drawable/steampunk_hour_hand.png b/wear/src/main/res/drawable/steampunk_hour_hand.png new file mode 100644 index 0000000000..f0031095d8 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_hour_hand.png differ diff --git a/wear/src/main/res/drawable/steampunk_minute_hand.png b/wear/src/main/res/drawable/steampunk_minute_hand.png new file mode 100644 index 0000000000..8b703d1b21 Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_minute_hand.png differ diff --git a/wear/src/main/res/drawable/steampunk_pointer.png b/wear/src/main/res/drawable/steampunk_pointer.png new file mode 100644 index 0000000000..60792cd48a Binary files /dev/null and b/wear/src/main/res/drawable/steampunk_pointer.png differ diff --git a/wear/src/main/res/drawable/watchface_steampunk.png b/wear/src/main/res/drawable/watchface_steampunk.png new file mode 100644 index 0000000000..0db24e5faa Binary files /dev/null and b/wear/src/main/res/drawable/watchface_steampunk.png differ diff --git a/wear/src/main/res/layout/activity_steampunk.xml b/wear/src/main/res/layout/activity_steampunk.xml new file mode 100644 index 0000000000..3fa994d818 --- /dev/null +++ b/wear/src/main/res/layout/activity_steampunk.xml @@ -0,0 +1,12 @@ + + \ No newline at end of file diff --git a/wear/src/main/res/layout/rect_steampunk.xml b/wear/src/main/res/layout/rect_steampunk.xml new file mode 100644 index 0000000000..832c27d005 --- /dev/null +++ b/wear/src/main/res/layout/rect_steampunk.xml @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wear/src/main/res/layout/round_steampunk.xml b/wear/src/main/res/layout/round_steampunk.xml new file mode 100644 index 0000000000..894164db00 --- /dev/null +++ b/wear/src/main/res/layout/round_steampunk.xml @@ -0,0 +1,381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wear/src/main/res/values/colors.xml b/wear/src/main/res/values/colors.xml index 0a20535687..2280e772d3 100644 --- a/wear/src/main/res/values/colors.xml +++ b/wear/src/main/res/values/colors.xml @@ -61,6 +61,7 @@ #FAFAFA #E0E0E0 #9E9E9E + #333333 diff --git a/wear/src/main/res/values/strings.xml b/wear/src/main/res/values/strings.xml index a7f34c08b1..0256d3a11f 100644 --- a/wear/src/main/res/values/strings.xml +++ b/wear/src/main/res/values/strings.xml @@ -20,6 +20,18 @@ 5 + + Low + Medium + High + + + + 1 + 2 + 3 + + Default Quick righty diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index 1846ce4939..0befaddfd0 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -141,6 +141,14 @@ android:summary="Input Design" android:title="Input Design" /> + +