diff --git a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java index f0e70c0a25..40fadff684 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -93,12 +93,22 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval { return (System.currentTimeMillis() - date) / (60 * 60 * 1000.0); } - public String age() { + public String age(boolean useShortText) { Map diff = computeDiff(date, System.currentTimeMillis()); - if (OverviewFragment.shorttextmode) - return diff.get(TimeUnit.DAYS) + "d" + diff.get(TimeUnit.HOURS) + "h"; - else - return diff.get(TimeUnit.DAYS) + " " + MainApp.gs(R.string.days) + " " + diff.get(TimeUnit.HOURS) + " " + MainApp.gs(R.string.hours); + + String days = " " + MainApp.gs(R.string.days) + " "; + String hours = " " + MainApp.gs(R.string.hours) + " "; + + if (useShortText) { + days = "d"; + hours = "h"; + } + + return diff.get(TimeUnit.DAYS) + days + diff.get(TimeUnit.HOURS) + hours; + } + + public String age() { + return age(OverviewFragment.shorttextmode); } public boolean isOlderThan(double hours) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/CareportalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/CareportalFragment.java index ab98682fb4..c7f6e1bf64 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/CareportalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/CareportalFragment.java @@ -22,12 +22,16 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.events.EventCareportalEventChange; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.common.SubscriberFragment; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.overview.OverviewFragment; +import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.FabricPrivacy; +import info.nightscout.androidaps.utils.SP; +import info.nightscout.androidaps.utils.SetWarnColor; public class CareportalFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(CareportalFragment.class); @@ -91,15 +95,15 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli view.findViewById(R.id.careportal_openapsoffline).setOnClickListener(this); view.findViewById(R.id.careportal_temporarytarget).setOnClickListener(this); - iage = (TextView) view.findViewById(R.id.careportal_insulinage); - cage = (TextView) view.findViewById(R.id.careportal_canulaage); - sage = (TextView) view.findViewById(R.id.careportal_sensorage); - pbage = (TextView) view.findViewById(R.id.careportal_pbage); + iage = view.findViewById(R.id.careportal_insulinage); + cage = view.findViewById(R.id.careportal_canulaage); + sage = view.findViewById(R.id.careportal_sensorage); + pbage = view.findViewById(R.id.careportal_pbage); statsLayout = view.findViewById(R.id.careportal_stats); noProfileView = view.findViewById(R.id.profileview_noprofile); - butonsLayout = (LinearLayout) view.findViewById(R.id.careportal_buttons); + butonsLayout = view.findViewById(R.id.careportal_buttons); ProfileStore profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null ? ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() : null; if (profileStore == null) { @@ -249,13 +253,17 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli } private static TextView handleAge(final TextView age, String eventType, double warnThreshold, double urgentThreshold) { - String notavailable = OverviewFragment.shorttextmode ? "-" : MainApp.gs(R.string.notavailable); + return handleAge(age, "", eventType, warnThreshold, urgentThreshold, OverviewFragment.shorttextmode); + } + + public static TextView handleAge(final TextView age, String prefix, String eventType, double warnThreshold, double urgentThreshold, boolean useShortText) { + String notavailable = useShortText ? "-" : MainApp.gs(R.string.notavailable); if (age != null) { CareportalEvent careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(eventType); if (careportalEvent != null) { age.setTextColor(CareportalFragment.determineTextColor(careportalEvent, warnThreshold, urgentThreshold)); - age.setText(careportalEvent.age()); + age.setText(prefix + careportalEvent.age(useShortText)); } else { age.setText(notavailable); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index 41c0611ce4..ded61339ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -4,8 +4,6 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.NotificationManager; -import androidx.arch.core.util.Function; - import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; @@ -60,7 +58,6 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.QuickWizardEntry; import info.nightscout.androidaps.db.BgReading; -import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.Source; @@ -92,7 +89,6 @@ import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatm import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus; -import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity; import info.nightscout.androidaps.plugins.general.overview.dialogs.CalibrationDialog; import info.nightscout.androidaps.plugins.general.overview.dialogs.NewCarbsDialog; @@ -258,17 +254,17 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, apsModeView = (TextView) view.findViewById(R.id.overview_apsmode); tempTargetView = (TextView) view.findViewById(R.id.overview_temptarget); - iage = (TextView) view.findViewById(R.id.careportal_insulinage); - cage = (TextView) view.findViewById(R.id.careportal_canulaage); - sage = (TextView) view.findViewById(R.id.careportal_sensorage); - pbage = (TextView) view.findViewById(R.id.careportal_pbage); + iage = view.findViewById(R.id.careportal_insulinage); + cage = view.findViewById(R.id.careportal_canulaage); + sage = view.findViewById(R.id.careportal_sensorage); + pbage = view.findViewById(R.id.careportal_pbage); - iageView = (TextView) view.findViewById(R.id.overview_insulinage); - cageView = (TextView) view.findViewById(R.id.overview_canulaage); - reservoirView = (TextView) view.findViewById(R.id.overview_reservoirlevel); - sageView = (TextView) view.findViewById(R.id.overview_sensorage); - batteryView = (TextView) view.findViewById(R.id.overview_batterylevel); - statuslightsLayout = (LinearLayout) view.findViewById(R.id.overview_statuslights); + iageView = view.findViewById(R.id.overview_insulinage); + cageView = view.findViewById(R.id.overview_canulaage); + reservoirView = view.findViewById(R.id.overview_reservoirlevel); + sageView = view.findViewById(R.id.overview_sensorage); + batteryView = view.findViewById(R.id.overview_batterylevel); + statuslightsLayout = view.findViewById(R.id.overview_statuslights); bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph); iobGraph = (GraphView) view.findViewById(R.id.overview_iobgraph); @@ -1324,54 +1320,22 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, cobView.setText(cobText); } - if (statuslightsLayout != null) { - if (SP.getBoolean(R.string.key_show_statuslights, false)) { - CareportalEvent careportalEvent; - NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance(); - double iageUrgent = nsSettings.getExtendedWarnValue("iage", "urgent", 96); - double iageWarn = nsSettings.getExtendedWarnValue("iage", "warn", 72); - double cageUrgent = nsSettings.getExtendedWarnValue("cage", "urgent", 72); - double cageWarn = nsSettings.getExtendedWarnValue("cage", "warn", 48); - double sageUrgent = nsSettings.getExtendedWarnValue("sage", "urgent", 166); - double sageWarn = nsSettings.getExtendedWarnValue("sage", "warn", 164); - //double pbageUrgent = nsSettings.getExtendedWarnValue("pgage", "urgent", 360); - //double pbageWarn = nsSettings.getExtendedWarnValue("pgage", "warn", 240); - double batUrgent = SP.getDouble(R.string.key_statuslights_bat_critical, 5.0); - double batWarn = SP.getDouble(R.string.key_statuslights_bat_warning, 25.0); - double resUrgent = SP.getDouble(R.string.key_statuslights_res_critical, 10.0); - double resWarn = SP.getDouble(R.string.key_statuslights_res_warning, 80.0); + if (statuslightsLayout != null && SP.getBoolean(R.string.key_show_statuslights, false)) { + StatuslightHandler handler = new StatuslightHandler(); - if (cageView != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SITECHANGE); - double canAge = careportalEvent != null ? careportalEvent.getHoursFromStart() : Double.MAX_VALUE; - applyStatuslight(cageView, "CAN", canAge, cageWarn, cageUrgent, Double.MAX_VALUE, true); - } + if (SP.getBoolean(R.string.key_show_statuslights_easy, false)) { + handler.statuslight(cageView, iageView, reservoirView, sageView, batteryView); - if (iageView != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.INSULINCHANGE); - double insulinAge = careportalEvent != null ? careportalEvent.getHoursFromStart() : Double.MAX_VALUE; - applyStatuslight(iageView, "INS", insulinAge, iageWarn, iageUrgent, Double.MAX_VALUE, true); - } + statuslightsLayout.setVisibility(View.VISIBLE); + } else if (SP.getBoolean(R.string.key_show_statuslights_extended, false)) { + handler.extendedStatuslight(cageView, iageView, reservoirView, sageView, batteryView); - if (reservoirView != null) { - double reservoirLevel = pump.isInitialized() ? pump.getReservoirLevel() : -1; - applyStatuslight(reservoirView, "RES", reservoirLevel, resWarn, resUrgent, -1, false); - } - - if (sageView != null) { - careportalEvent = MainApp.getDbHelper().getLastCareportalEvent(CareportalEvent.SENSORCHANGE); - double sensorAge = careportalEvent != null ? careportalEvent.getHoursFromStart() : Double.MAX_VALUE; - applyStatuslight(sageView, "SEN", sensorAge, sageWarn, sageUrgent, Double.MAX_VALUE, true); - } - - if (batteryView != null) { - double batteryLevel = pump.isInitialized() ? pump.getBatteryLevel() : -1; - applyStatuslight(batteryView, "BAT", batteryLevel, batWarn, batUrgent, -1, false); - } statuslightsLayout.setVisibility(View.VISIBLE); } else { statuslightsLayout.setVisibility(View.GONE); } + } else if (statuslightsLayout != null) { + statuslightsLayout.setVisibility(View.GONE); } boolean predictionsAvailable; @@ -1559,21 +1523,5 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, Profiler.log(log, from, updateGUIStart); } - public static void applyStatuslight(TextView view, String text, double value, double warnThreshold, double urgentThreshold, double invalid, boolean checkAscending) { - Function check = checkAscending ? (Double threshold) -> value >= threshold : (Double threshold) -> value <= threshold; - if (value != invalid) { - view.setText(text); - if (check.apply(urgentThreshold)) { - view.setTextColor(MainApp.gc(R.color.ribbonCritical)); - } else if (check.apply(warnThreshold)) { - view.setTextColor(MainApp.gc(R.color.ribbonWarning)); - } else { - view.setTextColor(MainApp.gc(R.color.ribbonDefault)); - } - view.setVisibility(View.VISIBLE); - } else { - view.setVisibility(View.GONE); - } - } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java new file mode 100644 index 0000000000..ee295b9447 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatuslightHandler.java @@ -0,0 +1,135 @@ +package info.nightscout.androidaps.plugins.general.overview; + +import android.view.View; +import android.widget.TextView; + +import androidx.arch.core.util.Function; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; +import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; +import info.nightscout.androidaps.utils.DecimalFormatter; +import info.nightscout.androidaps.utils.SP; +import info.nightscout.androidaps.utils.SetWarnColor; + +class StatuslightHandler { + + /** + * applies the statuslight subview on the overview fragement + */ + void statuslight(TextView cageView, TextView iageView, TextView reservoirView, + TextView sageView, TextView batteryView) { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + + applyStatuslight("cage", CareportalEvent.SITECHANGE, cageView, "CAN", 48, 72); + applyStatuslight("iage", CareportalEvent.INSULINCHANGE, iageView, "INS", 72, 96); + + double reservoirLevel = pump.isInitialized() ? pump.getReservoirLevel() : -1; + applyStatuslightLevel(R.string.key_statuslights_res_critical, 10.0, + R.string.key_statuslights_res_warning, 80.0, reservoirView, "RES", reservoirLevel); + + applyStatuslight("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN", 164, 166); + + double batteryLevel = pump.isInitialized() ? pump.getBatteryLevel() : -1; + applyStatuslightLevel(R.string.key_statuslights_bat_critical, 5.0, + R.string.key_statuslights_bat_warning, 22.0, + batteryView, "BAT", batteryLevel); + + } + + void applyStatuslight(String nsSettingPlugin, String eventName, TextView view, String text, + int defaultWarnThreshold, int defaultUrgentThreshold) { + NSSettingsStatus nsSettings = NSSettingsStatus.getInstance(); + + if (view != null) { + double urgent = nsSettings.getExtendedWarnValue(nsSettingPlugin, "urgent", defaultUrgentThreshold); + double warn = nsSettings.getExtendedWarnValue(nsSettingPlugin, "warn", defaultWarnThreshold); + CareportalEvent event = MainApp.getDbHelper().getLastCareportalEvent(eventName); + double age = event != null ? event.getHoursFromStart() : Double.MAX_VALUE; + applyStatuslight(view, text, age, warn, urgent, Double.MAX_VALUE, true); + } + } + + void applyStatuslightLevel(int criticalSetting, double criticalDefaultValue, + int warnSetting, double warnDefaultValue, + TextView view, String text, double level) { + if (view != null) { + double resUrgent = SP.getDouble(criticalSetting, criticalDefaultValue); + double resWarn = SP.getDouble(warnSetting, warnDefaultValue); + applyStatuslight(view, text, level, resWarn, resUrgent, -1, false); + } + } + + void applyStatuslight(TextView view, String text, double value, double warnThreshold, + double urgentThreshold, double invalid, boolean checkAscending) { + Function check = checkAscending ? (Double threshold) -> value >= threshold : + (Double threshold) -> value <= threshold; + if (value != invalid) { + view.setText(text); + if (check.apply(urgentThreshold)) { + view.setTextColor(MainApp.gc(R.color.ribbonCritical)); + } else if (check.apply(warnThreshold)) { + view.setTextColor(MainApp.gc(R.color.ribbonWarning)); + } else { + view.setTextColor(MainApp.gc(R.color.ribbonDefault)); + } + view.setVisibility(View.VISIBLE); + } else { + view.setVisibility(View.GONE); + } + + } + + /** + * applies the extended statuslight subview on the overview fragement + */ + void extendedStatuslight(TextView cageView, TextView iageView, + TextView reservoirView, TextView sageView, + TextView batteryView) { + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + + handleAge("cage", CareportalEvent.SITECHANGE, cageView, "CAN ", + 48, 72); + + handleAge("iage", CareportalEvent.INSULINCHANGE, iageView, "INS ", + 72, 96); + + handleLevel(R.string.key_statuslights_res_critical, 10.0, + R.string.key_statuslights_res_warning, 80.0, + reservoirView, "RES ", pump.getReservoirLevel()); + + handleAge("sage", CareportalEvent.SENSORCHANGE, sageView, "SEN ", + 164, 166); + + handleLevel(R.string.key_statuslights_bat_critical, 26.0, + R.string.key_statuslights_bat_warning, 51.0, + batteryView, "BAT ", pump.getBatteryLevel()); + } + + void handleAge(String nsSettingPlugin, String eventName, TextView view, String text, + int defaultWarnThreshold, int defaultUrgentThreshold) { + NSSettingsStatus nsSettings = new NSSettingsStatus().getInstance(); + + if (view != null) { + double urgent = nsSettings.getExtendedWarnValue(nsSettingPlugin, "urgent", defaultUrgentThreshold); + double warn = nsSettings.getExtendedWarnValue(nsSettingPlugin, "warn", defaultWarnThreshold); + CareportalFragment.handleAge(view, text, eventName, warn, urgent, true); + } + } + + void handleLevel(int criticalSetting, double criticalDefaultValue, + int warnSetting, double warnDefaultValue, + TextView view, String text, double level) { + if (view != null) { + double resUrgent = SP.getDouble(criticalSetting, criticalDefaultValue); + double resWarn = SP.getDouble(warnSetting, warnDefaultValue); + view.setText(text + DecimalFormatter.to0Decimal(level)); + SetWarnColor.setColor(view, level, resWarn, resUrgent); + } + } + +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7af0131011..00898c6275 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -623,8 +623,13 @@ Enable superbolus in wizard Enable superbolus functionality in wizard. Do not enable until you learn what it really does. IT MAY CAUSE INSULIN OVERDOSE IF USED BLINDLY! key_show_statuslights + key_show_statuslights_easy + key_show_statuslights_extended Show status lights on home screen - Enable status lights for cage, iage, sage, reservoir and battery level on home screen. + Show original status lights on home screen + Enable original status lights for cage, iage, sage, reservoir and battery level on home screen. + Show extended status lights on home screen + Enable extended status lights for cage, iage, sage, reservoir and battery level on home screen. key_statuslights_res_warning Threshold warning reservoir level [U] key_statuslights_res_critical diff --git a/app/src/main/res/xml/pref_overview.xml b/app/src/main/res/xml/pref_overview.xml index 67bcdb6d10..996f5591cd 100644 --- a/app/src/main/res/xml/pref_overview.xml +++ b/app/src/main/res/xml/pref_overview.xml @@ -165,9 +165,22 @@ + + + +