From 8db3f258cde0ff01f183bc119fbd5bb0b61bab13 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 10 Feb 2017 16:53:39 +0100 Subject: [PATCH] xdrip calibration --- app/build.gradle | 4 +- .../androidaps/Services/Intents.java | 2 + .../androidaps/data/GlucoseStatus.java | 51 ++++++++ .../androidaps/db/DatabaseHelper.java | 42 ------ .../Overview/Dialogs/CalibrationDialog.java | 121 ++++++++++++++++++ .../Overview/Dialogs/WizardDialog.java | 3 +- .../plugins/Overview/OverviewFragment.java | 26 +++- .../SmsCommunicatorPlugin.java | 4 +- .../wearintegration/WatchUpdaterService.java | 4 +- .../PersistentNotificationPlugin.java | 2 +- .../layout/overview_calibration_dialog.xml | 86 +++++++++++++ app/src/main/res/layout/overview_fragment.xml | 33 +++-- app/src/main/res/values-cs/strings.xml | 5 + app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 7 +- wear/wear.iml | 16 +-- 16 files changed, 335 insertions(+), 72 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java create mode 100644 app/src/main/res/layout/overview_calibration_dialog.xml diff --git a/app/build.gradle b/app/build.gradle index ec7e25f692..4993962079 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -70,7 +70,7 @@ android { dimension "limits" buildConfigField "int", "MAXBOLUS", "5" } - full { + full { dimension "standard" buildConfigField "boolean", "APS", "true" buildConfigField "boolean", "PUMPDRIVERS", "true" @@ -146,4 +146,4 @@ dependencies { androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.2" compile(name:'android-edittext-validator-v1.3.4-mod', ext:'aar') -} +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java index e46071e7ff..921b04b936 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/Intents.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/Intents.java @@ -31,4 +31,6 @@ public interface Intents { String ACTION_NEW_BG_ESTIMATE_NO_DATA = "com.eveningoutpost.dexdrip.BgEstimateNoData"; String NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR"; + + String ACTION_REMOTE_CALIBRATION = "com.eveningoutpost.dexdrip.NewCalibration"; } diff --git a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java index 9a28e56359..9fc8bd0ff4 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java @@ -6,6 +6,14 @@ import android.support.annotation.Nullable; import android.text.Html; import android.text.Spanned; +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.stmt.PreparedQuery; +import com.j256.ormlite.stmt.QueryBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -21,6 +29,7 @@ import info.nightscout.utils.Round; */ public class GlucoseStatus { + private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class); public double glucose = 0d; public double delta = 0d; public double avgdelta = 0d; @@ -124,6 +133,48 @@ public class GlucoseStatus { return status.round(); } + /* + * Return last BgReading from database or null if db is empty + */ + @Nullable + public static BgReading lastBg() { + List bgList = null; + + try { + Dao daoBgReadings = MainApp.getDbHelper().getDaoBgReadings(); + QueryBuilder queryBuilder = daoBgReadings.queryBuilder(); + queryBuilder.orderBy("timeIndex", false); + queryBuilder.limit(1L); + queryBuilder.where().gt("value", 38); + PreparedQuery preparedQuery = queryBuilder.prepare(); + bgList = daoBgReadings.query(preparedQuery); + + } catch (SQLException e) { + log.debug(e.getMessage(), e); + } + if (bgList != null && bgList.size() > 0) + return bgList.get(0); + else + return null; + } + + /* + * Return bg reading if not old ( <9 min ) + * or null if older + */ + @Nullable + public static BgReading actualBg() { + BgReading lastBg = lastBg(); + + if (lastBg == null) + return null; + + if (lastBg.timeIndex > new Date().getTime() - 9 * 60 * 1000) + return lastBg; + + return null; + } + public static double average(ArrayList array) { double sum = 0d; diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 923e29f0de..abaf1da7c3 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -172,48 +172,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return getDao(DanaRHistoryRecord.class); } - /* - * Return last BgReading from database or null if db is empty - */ - @Nullable - public BgReading lastBg() { - List bgList = null; - - try { - Dao daoBgReadings = getDaoBgReadings(); - QueryBuilder queryBuilder = daoBgReadings.queryBuilder(); - queryBuilder.orderBy("timeIndex", false); - queryBuilder.limit(1L); - queryBuilder.where().gt("value", 38); - PreparedQuery preparedQuery = queryBuilder.prepare(); - bgList = daoBgReadings.query(preparedQuery); - - } catch (SQLException e) { - log.debug(e.getMessage(), e); - } - if (bgList != null && bgList.size() > 0) - return bgList.get(0); - else - return null; - } - - /* - * Return bg reading if not old ( <9 min ) - * or null if older - */ - @Nullable - public BgReading actualBg() { - BgReading lastBg = lastBg(); - - if (lastBg == null) - return null; - - if (lastBg.timeIndex > new Date().getTime() - 9 * 60 * 1000) - return lastBg; - - return null; - } - public List getBgreadingsDataFromTime(long mills, boolean ascending) { try { Dao daoBgreadings = getDaoBgReadings(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java new file mode 100644 index 0000000000..1b7836242a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/CalibrationDialog.java @@ -0,0 +1,121 @@ +package info.nightscout.androidaps.plugins.Overview.Dialogs; + + +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.List; + +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.Services.Intents; +import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.client.data.NSProfile; +import info.nightscout.utils.PlusMinusEditText; +import info.nightscout.utils.SafeParse; +import info.nightscout.utils.ToastUtils; + +public class CalibrationDialog extends DialogFragment implements View.OnClickListener { + private static Logger log = LoggerFactory.getLogger(CalibrationDialog.class); + + Button okButton; + PlusMinusEditText bgText; + TextView unitsView; + + Context parentContext; + + public CalibrationDialog() { + // Required empty public constructor + } + + public void setContext(Context context) { + parentContext = context; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.overview_calibration_dialog, container, false); + + getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); + getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + + okButton = (Button) view.findViewById(R.id.overview_calibration_okbutton); + okButton.setOnClickListener(this); + + NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile(); + Double bg = NSProfile.fromMgdlToUnits(GlucoseStatus.getGlucoseStatusData() != null ? GlucoseStatus.getGlucoseStatusData().glucose : 0d, profile.getUnits()); + if (profile.getUnits().equals(Constants.MMOL)) + bgText = new PlusMinusEditText(view, R.id.overview_calibration_bg, R.id.overview_calibration_bg_plus, R.id.overview_calibration_bg_minus, bg, 0d, 30d, 0.1d, new DecimalFormat("0.0"), false); + else + bgText = new PlusMinusEditText(view, R.id.overview_calibration_bg, R.id.overview_calibration_bg_plus, R.id.overview_calibration_bg_minus, bg, 0d, 500d, 1d, new DecimalFormat("0"), false); + + unitsView = (TextView) view.findViewById(R.id.overview_calibration_units); + unitsView.setText(profile.getUnits()); + + return view; + } + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.overview_calibration_okbutton: + if (parentContext != null) { + final NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile(); + + final Double bg = bgText.getValue(); + + String confirmMessage = String.format(MainApp.sResources.getString(R.string.send_calibration), bg); + + AlertDialog.Builder builder = new AlertDialog.Builder(parentContext); + builder.setTitle(MainApp.sResources.getString(R.string.confirmation)); + builder.setMessage(confirmMessage); + builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + Context context = MainApp.instance().getApplicationContext(); + Bundle bundle = new Bundle(); + bundle.putDouble("glucose_number", bg); + bundle.putString("units", profile.getUnits().equals(Constants.MGDL) ? "mgdl" : "mmol"); + bundle.putLong("timestamp", new Date().getTime()); + Intent intent = new Intent(Intents.ACTION_REMOTE_CALIBRATION); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + List q = MainApp.instance().getApplicationContext().getPackageManager().queryBroadcastReceivers(intent, 0); + if (q.size() < 1) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.sResources.getString(R.string.xdripnotinstalled)); + log.debug(MainApp.sResources.getString(R.string.xdripnotinstalled)); + } else { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(),MainApp.sResources.getString(R.string.calibrationsent)); + } + } + }); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.show(); + dismiss(); + } else { + log.error("parentContext == null"); + } + break; + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java index 4d83f0a298..890c393edc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java @@ -36,6 +36,7 @@ import java.util.Date; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.interfaces.TempBasalsInterface; @@ -278,7 +279,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener { else editBg.setStep(0.1d); // Set BG if not old - BgReading lastBg = MainApp.getDbHelper().actualBg(); + BgReading lastBg = GlucoseStatus.actualBg(); if (lastBg != null) { Double lastBgValue = lastBg.valueToUnits(units); 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 2c80489033..a2f0bfe2b6 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 @@ -75,12 +75,14 @@ import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotificati import info.nightscout.androidaps.plugins.Objectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA; import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; +import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter; +import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin; import info.nightscout.androidaps.plugins.TempTargetRange.TempTargetRangePlugin; import info.nightscout.androidaps.plugins.TempTargetRange.events.EventTempTargetRangeChange; import info.nightscout.client.data.NSProfile; @@ -125,6 +127,7 @@ public class OverviewFragment extends Fragment { Button cancelTempButton; Button treatmentButton; Button wizardButton; + Button calibrationButton; Button acceptTempButton; Button quickWizardButton; @@ -172,6 +175,7 @@ public class OverviewFragment extends Fragment { acceptTempButton = (Button) view.findViewById(R.id.overview_accepttempbutton); acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout); quickWizardButton = (Button) view.findViewById(R.id.overview_quickwizard); + calibrationButton = (Button) view.findViewById(R.id.overview_calibration); showPredictionView = (CheckBox) view.findViewById(R.id.overview_showprediction); notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications); @@ -233,6 +237,15 @@ public class OverviewFragment extends Fragment { } }); + calibrationButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FragmentManager manager = getFragmentManager(); + CalibrationDialog calibrationDialog = new CalibrationDialog(); + calibrationDialog.setContext(getContext()); + calibrationDialog.show(manager, "CalibrationDialog"); + } + }); acceptTempButton.setOnClickListener(new View.OnClickListener() { @Override @@ -278,7 +291,7 @@ public class OverviewFragment extends Fragment { } void processQuickWizard() { - final BgReading lastBG = MainApp.getDbHelper().lastBg(); + final BgReading lastBG = GlucoseStatus.lastBg(); if (MainApp.getConfigBuilder() == null || ConfigBuilderPlugin.getActiveProfile() == null) // app not initialized yet return; final NSProfile profile = ConfigBuilderPlugin.getActiveProfile().getProfile(); @@ -465,8 +478,8 @@ public class OverviewFragment extends Fragment { @SuppressLint("SetTextI18n") public void updateGUI() { updateNotifications(); - BgReading actualBG = MainApp.getDbHelper().actualBg(); - BgReading lastBG = MainApp.getDbHelper().lastBg(); + BgReading actualBG = GlucoseStatus.actualBg(); + BgReading lastBG = GlucoseStatus.lastBg(); if (MainApp.getConfigBuilder() == null || MainApp.getConfigBuilder().getActiveProfile() == null || MainApp.getConfigBuilder().getActiveProfile().getProfile() == null) {// app not initialized yet initializingView.setText(R.string.noprofileset); @@ -571,6 +584,13 @@ public class OverviewFragment extends Fragment { acceptTempLayout.setVisibility(View.GONE); } + // **** Calibration button **** + if (MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && GlucoseStatus.actualBg() != null) { + calibrationButton.setVisibility(View.VISIBLE); + } else { + calibrationButton.setVisibility(View.GONE); + } + TempBasal activeTemp = pump.getTempBasal(); if (pump.isTempBasalInProgress()) { cancelTempLayout.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java index c072c88b59..7197eb99b2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorPlugin.java @@ -212,8 +212,8 @@ public class SmsCommunicatorPlugin implements PluginBase { if (splited.length > 0) { switch (splited[0].toUpperCase()) { case "BG": - BgReading actualBG = MainApp.getDbHelper().actualBg(); - BgReading lastBG = MainApp.getDbHelper().lastBg(); + BgReading actualBG = GlucoseStatus.actualBg(); + BgReading lastBG = GlucoseStatus.lastBg(); NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile(); String units = profile.getUnits(); 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 66383cf7d5..bdd978f10c 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 @@ -142,7 +142,7 @@ public class WatchUpdaterService extends WearableListenerService implements private void sendData() { - BgReading lastBG = MainApp.getDbHelper().lastBg(); + BgReading lastBG = GlucoseStatus.lastBg(); if (lastBG != null) { GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); @@ -250,7 +250,7 @@ public class WatchUpdaterService extends WearableListenerService implements private void resendData() { if(googleApiClient != null && !googleApiClient.isConnected() && !googleApiClient.isConnecting()) { googleApiConnect(); } long startTime = System.currentTimeMillis() - (long)(60000 * 60 * 5.5); - BgReading last_bg = MainApp.getDbHelper().lastBg(); + BgReading last_bg = GlucoseStatus.lastBg(); if (last_bg == null) return; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/persistentnotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/persistentnotification/PersistentNotificationPlugin.java index 31e369889d..532959d926 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/persistentnotification/PersistentNotificationPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/persistentnotification/PersistentNotificationPlugin.java @@ -108,7 +108,7 @@ public class PersistentNotificationPlugin implements PluginBase{ NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile(); - BgReading lastBG = MainApp.getDbHelper().lastBg(); + BgReading lastBG = GlucoseStatus.lastBg(); GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); if(profile != null && lastBG != null) { diff --git a/app/src/main/res/layout/overview_calibration_dialog.xml b/app/src/main/res/layout/overview_calibration_dialog.xml new file mode 100644 index 0000000000..cff9d0dab1 --- /dev/null +++ b/app/src/main/res/layout/overview_calibration_dialog.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + +