diff --git a/.gitignore b/.gitignore index 79927b784d..1cd8d2622a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ *.apk build/ .idea/ +app/src/main/jniLibs diff --git a/app/build.gradle b/app/build.gradle index b83ba004c1..75a930e03b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -158,6 +158,14 @@ android { buildConfigField "boolean", "PUMPCONTROL", "false" } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + testOptions { + unitTests.returnDefaultValues = true + } } allprojects { @@ -179,6 +187,7 @@ dependencies { compile("com.crashlytics.sdk.android:answers:1.3.12@aar") { transitive = true; } + compile 'MilosKozak:danars-support-lib:master@zip' compile "com.android.support:appcompat-v7:${supportLibraryVersion}" compile "com.android.support:support-v4:${supportLibraryVersion}" @@ -188,6 +197,7 @@ dependencies { compile "com.android.support:design:${supportLibraryVersion}" compile "com.android.support:percent:${supportLibraryVersion}" compile "com.wdullaer:materialdatetimepicker:2.3.0" + compile 'com.android.support.constraint:constraint-layout:1.0.2' compile "com.squareup:otto:1.3.7" compile "com.j256.ormlite:ormlite-core:${ormLiteVersion}" compile "com.j256.ormlite:ormlite-android:${ormLiteVersion}" @@ -214,6 +224,8 @@ dependencies { compile "net.danlew:android.joda:2.9.9.1" + compile 'org.mozilla:rhino:1.7.7.2' + api "com.jakewharton:butterknife:8.8.1" annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1" @@ -231,3 +243,27 @@ dependencies { androidTestCompile "com.google.dexmaker:dexmaker:${dexmakerVersion}" androidTestCompile "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}" } + +task unzip(type: Copy) { + def zipPath = configurations.compile.find {it.name.startsWith("danars") } + def zipFile = file(zipPath) + def outputDir = file("${buildDir}/unpacked/dist") + + from zipTree(zipFile) + into outputDir +} + +task copyLibs(dependsOn: unzip, type: Copy) { + def src = file("${buildDir}/unpacked/dist/danars-support-lib-master") + def target = file("src/main/jniLibs/") + + from src + into target +} + +task full_clean(type: Delete) { + delete file("src/main/jniLibs") +} + +clean.dependsOn full_clean +preBuild.dependsOn copyLibs \ No newline at end of file diff --git a/app/libs/rhino-1.7.7.2.jar b/app/libs/rhino-1.7.7.2.jar deleted file mode 100644 index 4a18d33609..0000000000 Binary files a/app/libs/rhino-1.7.7.2.jar and /dev/null differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8290c46004..a36bdee3aa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -61,6 +61,7 @@ + 24 ? 6 : rangeToDisplay; + updateGUI("rangeChange"); + } + + @OnLongClick(R.id.historybrowse_zoom) + boolean onLongClickZoom() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(start); + calendar.set(Calendar.MILLISECOND, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.HOUR_OF_DAY, 0); + start = calendar.getTimeInMillis(); + updateGUI("resetToMidnight"); + iobCobCalculatorPlugin.clearCache(); + iobCobCalculatorPlugin.runCalculation("onLongClickZoom", start, true, eventCustomCalculationFinished); + return true; + } + + @OnClick(R.id.historybrowse_date) + void onClickDate() { + } + + @OnClick({R.id.overview_showbasals, R.id.overview_showprediction, R.id.overview_showiob, R.id.overview_showcob, R.id.overview_showdeviations, R.id.overview_showratios}) + void onClickDate(View view) { + //((CheckBox) view).toggle(); + updateGUI("checkboxToggle"); + iobCobCalculatorPlugin.clearCache(); + iobCobCalculatorPlugin.runCalculation("onClickDate", start, true, eventCustomCalculationFinished); + } + + + @Subscribe + public void onStatusEvent(final EventAutosensCalculationFinished e) { + Activity activity = this; + if (activity != null && e.cause == eventCustomCalculationFinished) { + log.debug("EventAutosensCalculationFinished"); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + updateGUI("EventAutosensCalculationFinished"); + } + }); + } + } + + void updateGUI(String from) { + final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final Profile profile = MainApp.getConfigBuilder().getProfile(); + final String units = profile.getUnits(); + + double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units)); + double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units)); + + if (lowLineSetting < 1) + lowLineSetting = Profile.fromMgdlToUnits(76d, units); + if (highLineSetting < 1) + highLineSetting = Profile.fromMgdlToUnits(180d, units); + + final double lowLine = lowLineSetting; + final double highLine = highLineSetting; + + final boolean showPrediction = false; + + int hoursToFetch; + final long toTime; + final long fromTime; + //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 { + fromTime = start + 100000; + toTime = start + rangeToDisplay * 60 * 60 * 1000L; + //} + + buttonDate.setText(DateUtil.dateAndTimeString(start)); + buttonZoom.setText(String.valueOf(rangeToDisplay)); + + log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime)); + + final long pointer = System.currentTimeMillis(); + + // ------------------ 1st graph + + final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin()); + + // **** In range Area **** + graphData.addInRangeArea(fromTime, toTime, lowLine, highLine); + + // **** BG **** + if (showPrediction) +//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed); + ; + else + graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null); + + // set manual x bounds to have nice steps + graphData.formatAxis(fromTime, toTime); + + // Treatments + graphData.addTreatments(fromTime, toTime); + + // add basal data + if (pump.getPumpDescription().isTempBasalCapable && showBasalsCheckbox.isChecked()) { + graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d); + } + + // **** NOW line **** + graphData.addNowLine(pointer); + + // ------------------ 2nd graph + + final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin); + + boolean useIobForScale = false; + boolean useCobForScale = false; + boolean useDevForScale = false; + boolean useRatioForScale = false; + + if (showIobCheckbox.isChecked()) { + useIobForScale = true; + } else if (showCobCheckbox.isChecked()) { + useCobForScale = true; + } else if (showDeviationsCheckbox.isChecked()) { + useDevForScale = true; + } else if (showRatiosCheckbox.isChecked()) { + useRatioForScale = true; + } + + if (showIobCheckbox.isChecked()) + secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d); + if (showCobCheckbox.isChecked()) + secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d); + if (showDeviationsCheckbox.isChecked()) + secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d); + if (showRatiosCheckbox.isChecked()) + secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d); + + // **** NOW line **** + // set manual x bounds to have nice steps + secondGraphData.formatAxis(fromTime, toTime); + secondGraphData.addNowLine(pointer); + + // do GUI update + if (showIobCheckbox.isChecked() || showCobCheckbox.isChecked() || showDeviationsCheckbox.isChecked() || showRatiosCheckbox.isChecked()) { + iobGraph.setVisibility(View.VISIBLE); + } else { + iobGraph.setVisibility(View.GONE); + } + // finally enforce drawing of graphs + graphData.performUpdate(); + secondGraphData.performUpdate(); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index e77be36ba6..91446ada32 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -35,9 +35,9 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.Services.AlarmSoundService; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.events.EventAppExit; +import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginBase; @@ -112,9 +112,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe runOnUiThread(new Runnable() { @Override public void run() { - if(ev.recreate) { + if (ev.recreate) { recreate(); - }else { + } else { try { // activity may be destroyed setUpTabs(true); } catch (IllegalStateException e) { @@ -171,7 +171,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe // Added in 1.57 at 21.01.2018 Integer unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30); SP.remove(R.string.key_pump_unreachable_threshold); - if(unreachable_threshold < 30) unreachable_threshold = 30; + if (unreachable_threshold < 30) unreachable_threshold = 30; SP.putString(R.string.key_pump_unreachable_threshold, unreachable_threshold.toString()); } @@ -222,6 +222,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe super.onResume(); askForSMSPermissions(); askForLocationPermissions(); + MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN)); } @Override @@ -358,6 +359,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe } }, null); break; + case R.id.nav_historybrowser: + startActivity(new Intent(v.getContext(), HistoryBrowseActivity.class)); + break; case R.id.nav_resetdb: new AlertDialog.Builder(v.getContext()) .setTitle(R.string.nav_resetdb) @@ -386,7 +390,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe case R.id.nav_about: AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext()); builder.setTitle(getString(R.string.app_name) + " " + BuildConfig.VERSION); - if (Config.NSCLIENT|| Config.G5UPLOADER) + if (Config.NSCLIENT || Config.G5UPLOADER) builder.setIcon(R.mipmap.yellowowl); else builder.setIcon(R.mipmap.blueowl); diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index ea037b362e..412383c6e1 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -47,7 +47,6 @@ import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; import info.nightscout.androidaps.plugins.Persistentnotification.PersistentNotificationPlugin; -import info.nightscout.androidaps.plugins.ProfileCircadianPercentage.CircadianPercentageProfileFragment; import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin; @@ -73,6 +72,7 @@ import info.nightscout.androidaps.plugins.XDripStatusline.StatuslinePlugin; import info.nightscout.androidaps.receivers.DataReceiver; import info.nightscout.androidaps.receivers.KeepAliveReceiver; import info.nightscout.androidaps.receivers.NSAlarmReceiver; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import io.fabric.sdk.android.Fabric; @@ -98,18 +98,26 @@ public class MainApp extends Application { @Override public void onCreate() { super.onCreate(); - Fabric.with(this, new Crashlytics()); - Fabric.with(this, new Answers()); + sInstance = this; + sResources = getResources(); + + try { + if (FabricPrivacy.fabricEnabled()) { + Fabric.with(this, new Crashlytics()); + Fabric.with(this, new Answers()); + Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION); + } + } catch (Exception e) { + android.util.Log.e("ANDROIDAPS", "Error with Fabric init! " + e); + } + JodaTimeAndroid.init(this); - Crashlytics.setString("BUILDVERSION", BuildConfig.BUILDVERSION); + log.info("Version: " + BuildConfig.VERSION_NAME); log.info("BuildVersion: " + BuildConfig.BUILDVERSION); sBus = Config.logEvents ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY); - sInstance = this; - sResources = getResources(); - registerLocalBroadcastReceiver(); if (pluginsList == null) { @@ -131,7 +139,7 @@ public class MainApp extends Application { if (Config.DANAR) pluginsList.add(DanaRv2Plugin.getPlugin()); if (Config.DANAR) pluginsList.add(DanaRSPlugin.getPlugin()); pluginsList.add(CareportalPlugin.getPlugin()); - if (Config.DANAR) pluginsList.add(InsightPumpPlugin.getPlugin()); + // if (Config.DANAR) pluginsList.add(InsightPumpPlugin.getPlugin()); // <-- Enable Insight plugin here if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin()); if (Config.VIRTUALPUMP) pluginsList.add(VirtualPumpPlugin.getPlugin()); if (Config.APS) pluginsList.add(LoopPlugin.getPlugin()); @@ -141,8 +149,6 @@ public class MainApp extends Application { pluginsList.add(NSProfilePlugin.getPlugin()); if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin()); if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin()); - if (Config.OTHERPROFILES) - pluginsList.add(CircadianPercentageProfileFragment.getPlugin()); pluginsList.add(TreatmentsPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin()); @@ -170,15 +176,15 @@ public class MainApp extends Application { } NSUpload.uploadAppStart(); if (Config.NSCLIENT) - Answers.getInstance().logCustom(new CustomEvent("AppStart-NSClient")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-NSClient")); else if (Config.G5UPLOADER) - Answers.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-G5Uploader")); else if (Config.PUMPCONTROL) - Answers.getInstance().logCustom(new CustomEvent("AppStart-PumpControl")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-PumpControl")); else if (MainApp.getConfigBuilder().isClosedModeEnabled()) - Answers.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-ClosedLoop")); else - Answers.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AppStart-OpenLoop")); new Thread(new Runnable() { @Override diff --git a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java index ae3982ad68..4ea3a80d3a 100644 --- a/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/PreferencesActivity.java @@ -130,6 +130,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre addPreferencesFromResource(id); addPreferencesFromResource(R.xml.pref_advanced); } else { + addPreferencesFromResource(R.xml.pref_overview); + if (!Config.NSCLIENT && !Config.G5UPLOADER) { addPreferencesFromResource(R.xml.pref_password); } diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java index b242c4c099..2bb7d8f9f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java @@ -600,7 +600,8 @@ public class DataService extends IntentService { if (trJson.has("eventType") && trJson.getString("eventType").equals(CareportalEvent.ANNOUNCEMENT)) { long date = trJson.getLong("mills"); long now = System.currentTimeMillis(); - if (date > now - 15 * 60 * 1000L && trJson.has("notes")) { + if (date > now - 15 * 60 * 1000L && trJson.has("notes") + && !(trJson.has("enteredBy") && trJson.getString("enteredBy").equals(SP.getString("careportal_enteredby", "AndroidAPS")))) { Notification announcement = new Notification(Notification.NSANNOUNCEMENT, trJson.getString("notes"), Notification.ANNOUNCEMENT, 60); MainApp.bus().post(new EventNewNotification(announcement)); } diff --git a/app/src/main/java/info/nightscout/androidaps/data/Profile.java b/app/src/main/java/info/nightscout/androidaps/data/Profile.java index 7bb693ef23..f461c84b2e 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -2,7 +2,7 @@ package info.nightscout.androidaps.data; import android.support.v4.util.LongSparseArray; -import com.crashlytics.android.Crashlytics; + import org.json.JSONArray; import org.json.JSONException; @@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.ToastUtils; public class Profile { @@ -57,7 +58,7 @@ public class Profile { if (units != null) this.units = units; else { - Crashlytics.log("Profile failover failed too"); + FabricPrivacy.log("Profile failover failed too"); this.units = Constants.MGDL; } } @@ -413,6 +414,8 @@ public class Profile { } public String getBasalList() { + if (basal_v == null) + basal_v = convertToSparseArray(basal); return getValuesList(basal_v, null, new DecimalFormat("0.00"), "U"); } diff --git a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java index 35a7265f2a..b08926f119 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java @@ -82,9 +82,9 @@ public class QuickWizardEntry { double cob = 0d; AutosensData autosensData; if (_synchronized) - autosensData = IobCobCalculatorPlugin.getLastAutosensDataSynchronized("QuickWizard COB"); + autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("QuickWizard COB"); else - autosensData = IobCobCalculatorPlugin.getLastAutosensData("QuickWizard COB"); + autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("QuickWizard COB"); if (autosensData != null && useCOB() == YES) { cob = autosensData.cob; 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 9f49b64280..e2e4e6d639 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/app/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -5,6 +5,7 @@ import android.graphics.Color; import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.table.DatabaseTable; +import org.apache.commons.lang3.StringUtils; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; @@ -184,7 +185,7 @@ public class CareportalEvent implements DataPointWithLabelInterface { try { JSONObject object = new JSONObject(json); if (object.has("notes")) - return object.getString("notes"); + return StringUtils.abbreviate(object.getString("notes"), 40); } catch (JSONException e) { log.error("Unhandled exception", e); } diff --git a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java index 78e1fb6282..4b4bfcb08d 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java +++ b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java @@ -16,6 +16,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.Overview.OverviewPlugin; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries; import info.nightscout.utils.DateUtil; @@ -121,7 +122,7 @@ public class Treatment implements DataPointWithLabelInterface { @Override public double getY() { - return yValue; + return isSMB ? OverviewPlugin.getPlugin().determineLowLine() : yValue; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventCustomCalculationFinished.java b/app/src/main/java/info/nightscout/androidaps/events/EventCustomCalculationFinished.java new file mode 100644 index 0000000000..e52761dc58 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/events/EventCustomCalculationFinished.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.events; + +/** + * Created by mike on 13.02.2018. + */ + +public class EventCustomCalculationFinished extends Event { +} diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventFeatureRunning.java b/app/src/main/java/info/nightscout/androidaps/events/EventFeatureRunning.java new file mode 100644 index 0000000000..0d07cd6c61 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/events/EventFeatureRunning.java @@ -0,0 +1,36 @@ +package info.nightscout.androidaps.events; + +/** + * Created by jamorham on 07/02/2018. + * + * Event to indicate that an app feature is being used, for example bolus wizard being opened + * + * The purpose this has been created for is to enable opportunistic connection to the pump + * so that it is already connected before the user wishes to enact a pump function + * + */ + +public class EventFeatureRunning extends Event { + + private Feature feature = Feature.UNKNOWN; + + public EventFeatureRunning() { + } + + public EventFeatureRunning(Feature feature) { + this.feature = feature; + } + + public Feature getFeature() { + return feature; + } + + public enum Feature { + UNKNOWN, + MAIN, + WIZARD, + + JUST_ADD_MORE_HERE + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java index 701b226031..86e33d618d 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java @@ -27,6 +27,8 @@ public class PumpDescription { public double tempAbsoluteStep = 0.05d; public int tempDurationStep = 60; + public boolean tempDurationStep15mAllowed = false; + public boolean tempDurationStep30mAllowed = false; public int tempMaxDuration = 12 * 60; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java index d6f56e501b..0edf29c1e4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java @@ -9,8 +9,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; + import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -32,6 +31,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SingleClickButton; /** @@ -83,7 +83,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -137,11 +137,11 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL extendedBolus.setVisibility(View.GONE); extendedBolusCancel.setVisibility(View.GONE); } else { - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { + ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (activeExtendedBolus != null) { extendedBolus.setVisibility(View.GONE); extendedBolusCancel.setVisibility(View.VISIBLE); - ExtendedBolus running = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); - extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + running.toString()); + extendedBolusCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + activeExtendedBolus.toString()); } else { extendedBolus.setVisibility(View.VISIBLE); extendedBolusCancel.setVisibility(View.GONE); @@ -153,10 +153,10 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL tempBasal.setVisibility(View.GONE); tempBasalCancel.setVisibility(View.GONE); } else { - if (MainApp.getConfigBuilder().isTempBasalInProgress()) { + final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); + if (activeTemp != null) { tempBasal.setVisibility(View.GONE); tempBasalCancel.setVisibility(View.VISIBLE); - final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); tempBasalCancel.setText(MainApp.instance().getString(R.string.cancel) + " " + activeTemp.toStringShort()); } else { tempBasal.setVisibility(View.VISIBLE); @@ -203,13 +203,13 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL case R.id.actions_extendedbolus_cancel: if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { ConfigBuilderPlugin.getCommandQueue().cancelExtended(null); - Answers.getInstance().logCustom(new CustomEvent("CancelExtended")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelExtended")); } break; case R.id.actions_canceltempbasal: if (MainApp.getConfigBuilder().isTempBasalInProgress()) { ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, null); - Answers.getInstance().logCustom(new CustomEvent("CancelTemp")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("CancelTemp")); } break; case R.id.actions_settempbasal: diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java index 23fa39066f..8297e28412 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java @@ -14,7 +14,6 @@ import android.view.Window; import android.view.WindowManager; import android.widget.Button; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import org.slf4j.Logger; @@ -31,6 +30,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -171,7 +171,7 @@ public class FillDialog extends DialogFragment implements OnClickListener { } } }); - Answers.getInstance().logCustom(new CustomEvent("Fill")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); } } }); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java index dc6a356f1d..e2bcbe2acd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewExtendedBolusDialog.java @@ -10,7 +10,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import org.slf4j.Logger; @@ -24,6 +23,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; @@ -99,7 +99,7 @@ public class NewExtendedBolusDialog extends DialogFragment implements View.OnCli } } }); - Answers.getInstance().logCustom(new CustomEvent("ExtendedBolus")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ExtendedBolus")); } }); builder.setNegativeButton(getString(R.string.cancel), null); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java index ce3d45fc71..8e5c1737c9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/NewTempBasalDialog.java @@ -1,6 +1,5 @@ package info.nightscout.androidaps.plugins.Actions.dialogs; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; @@ -13,7 +12,6 @@ import android.widget.LinearLayout; import android.widget.RadioButton; import android.widget.RadioGroup; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import org.slf4j.Logger; @@ -28,6 +26,7 @@ import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; @@ -162,7 +161,7 @@ public class NewTempBasalDialog extends DialogFragment implements View.OnClickLi } else { ConfigBuilderPlugin.getCommandQueue().tempBasalAbsolute(finalBasal, finalDurationInMinutes, true, callback); } - Answers.getInstance().logCustom(new CustomEvent("TempBasal")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("TempBasal")); } }); builder.setNegativeButton(getString(R.string.cancel), null); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java index 4070bc880f..701d050cee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/CareportalFragment.java @@ -10,7 +10,6 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import info.nightscout.androidaps.BuildConfig; @@ -24,6 +23,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.OverviewFragment; +import info.nightscout.utils.FabricPrivacy; public class CareportalFragment extends SubscriberFragment implements View.OnClickListener { @@ -111,7 +111,7 @@ public class CareportalFragment extends SubscriberFragment implements View.OnCli updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; 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 58d0603301..892d6491d4 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 @@ -23,7 +23,6 @@ import android.widget.RadioButton; import android.widget.Spinner; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout; @@ -38,6 +37,7 @@ import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; @@ -45,6 +45,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; @@ -54,6 +55,7 @@ import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.DateUtil; import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; @@ -407,12 +409,23 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick else layout.setVisibility(View.GONE); } + private void updateBGforDateTime() { + long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000 + List data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true); + if ((data.size() > 0) && + (data.get(0).date > millis - 7 * 60 * 1000L) && + (data.get(0).date < millis + 7 * 60 * 1000L)) { + editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL)); + } + } + @Override public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { eventTime.setYear(year - 1900); eventTime.setMonth(monthOfYear); eventTime.setDate(dayOfMonth); dateButton.setText(DateUtil.dateString(eventTime)); + updateBGforDateTime(); } @Override @@ -421,6 +434,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick eventTime.setMinutes(minute); eventTime.setSeconds(second); timeButton.setText(DateUtil.timeString(eventTime)); + updateBGforDateTime(); } @@ -685,14 +699,14 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick log.debug("Creating new TempTarget db record: " + tempTarget.toString()); MainApp.getDbHelper().createOrUpdate(tempTarget); NSUpload.uploadCareportalEntryToNS(data); - Answers.getInstance().logCustom(new CustomEvent("TempTarget")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("TempTarget")); } } catch (JSONException e) { log.error("Unhandled exception", e); } } else { NSUpload.uploadCareportalEntryToNS(data); - Answers.getInstance().logCustom(new CustomEvent("NSTreatment")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("NSTreatment")); } } }); @@ -727,7 +741,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick MainApp.bus().post(new EventNewBasalProfile()); } }); - Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch")); } public static void doProfileSwitch(final int duration, final int percentage, final int timeshift) { @@ -759,7 +773,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick MainApp.bus().post(new EventNewBasalProfile()); } }); - Answers.getInstance().logCustom(new CustomEvent("ProfileSwitch")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ProfileSwitch")); } else { log.error("No profile switch existing"); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java index 2e620eab70..8d4c74d607 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java @@ -17,8 +17,7 @@ import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; + import com.crashlytics.android.answers.CustomEvent; import java.util.ArrayList; @@ -40,6 +39,7 @@ import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.SensitivityOref0.SensitivityOref0Plugin; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.PasswordProtection; @@ -131,7 +131,7 @@ public class ConfigBuilderFragment extends Fragment { } return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -242,7 +242,7 @@ public class ConfigBuilderFragment extends Fragment { MainApp.bus().post(new EventRefreshGui()); MainApp.bus().post(new EventConfigBuilderChange()); getPlugin().logPluginStatus(); - Answers.getInstance().logCustom(new CustomEvent("ConfigurationChange")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); } }); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java index 1f0563bb0a..b1456c97b8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java @@ -49,6 +49,7 @@ import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; +import info.nightscout.utils.ToastUtils; /** * Created by mike on 05.08.2016. @@ -244,96 +245,90 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr ArrayList pluginsInCategory; // PluginBase.APS - pluginsInCategory = MainApp.getSpecificPluginsListByInterface(APSInterface.class); - activeAPS = (APSInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.APS); - if (activeAPS != null) { - if (Config.logConfigBuilder) - log.debug("Selected APS interface: " + ((PluginBase) activeAPS).getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activeAPS).getName())) { - p.setFragmentVisible(PluginBase.APS, false); - } - } - } + activeAPS = this.determineActivePlugin(APSInterface.class, PluginBase.APS); // PluginBase.INSULIN - pluginsInCategory = MainApp.getSpecificPluginsListByInterface(InsulinInterface.class); - activeInsulin = (InsulinInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.INSULIN); - if (Config.logConfigBuilder) - log.debug("Selected insulin interface: " + ((PluginBase) activeInsulin).getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activeInsulin).getName())) { - p.setFragmentVisible(PluginBase.INSULIN, false); - } - } + activeInsulin = this.determineActivePlugin(InsulinInterface.class, PluginBase.INSULIN); // PluginBase.SENSITIVITY - pluginsInCategory = MainApp.getSpecificPluginsListByInterface(SensitivityInterface.class); - activeSensitivity = (SensitivityInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.SENSITIVITY); - if (Config.logConfigBuilder) - log.debug("Selected sensitivity interface: " + ((PluginBase) activeSensitivity).getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activeSensitivity).getName())) { - p.setFragmentVisible(PluginBase.SENSITIVITY, false); - } - } + activeSensitivity = this.determineActivePlugin(SensitivityInterface.class, PluginBase.SENSITIVITY); // PluginBase.PROFILE - pluginsInCategory = MainApp.getSpecificPluginsListByInterface(ProfileInterface.class); - activeProfile = (ProfileInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.PROFILE); - if (Config.logConfigBuilder) - log.debug("Selected profile interface: " + ((PluginBase) activeProfile).getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activeProfile).getName())) { - p.setFragmentVisible(PluginBase.PROFILE, false); - } - } + activeProfile = this.determineActivePlugin(ProfileInterface.class, PluginBase.PROFILE); // PluginBase.BGSOURCE - pluginsInCategory = MainApp.getSpecificPluginsListByInterface(BgSourceInterface.class); - activeBgSource = (BgSourceInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.BGSOURCE); - if (Config.logConfigBuilder) - log.debug("Selected bgSource interface: " + ((PluginBase) activeBgSource).getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activeBgSource).getName())) { - p.setFragmentVisible(PluginBase.BGSOURCE, false); - } - } + activeBgSource = this.determineActivePlugin(BgSourceInterface.class, PluginBase.BGSOURCE); // PluginBase.PUMP pluginsInCategory = MainApp.getSpecificPluginsList(PluginBase.PUMP); activePump = (PumpInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.PUMP); if (activePump == null) activePump = VirtualPumpPlugin.getPlugin(); // for NSClient build - if (Config.logConfigBuilder) - log.debug("Selected pump interface: " + ((PluginBase) activePump).getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activePump).getName())) { - p.setFragmentVisible(PluginBase.PUMP, false); - } - } + this.setFragmentVisiblities(((PluginBase) activePump).getName(), pluginsInCategory, PluginBase.PUMP); // PluginBase.LOOP - pluginsInCategory = MainApp.getSpecificPluginsList(PluginBase.LOOP); - activeLoop = (LoopPlugin) getTheOneEnabledInArray(pluginsInCategory, PluginBase.LOOP); - if (activeLoop != null) { - if (Config.logConfigBuilder) - log.debug("Selected loop interface: " + activeLoop.getName()); - for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(activeLoop.getName())) { - p.setFragmentVisible(PluginBase.LOOP, false); - } - } - } + activeLoop = this.determineActivePlugin(PluginBase.LOOP); // PluginBase.TREATMENT - pluginsInCategory = MainApp.getSpecificPluginsList(PluginBase.TREATMENT); - activeTreatments = (TreatmentsInterface) getTheOneEnabledInArray(pluginsInCategory, PluginBase.TREATMENT); + activeTreatments = this.determineActivePlugin(PluginBase.TREATMENT); + } + + /** + * disables the visibility for all fragments of Plugins with the given PluginType + * which are not equally named to the Plugin implementing the given Plugin Interface. + * + * @param pluginInterface + * @param pluginType + * @param + * @return + */ + private T determineActivePlugin(Class pluginInterface, int pluginType) { + ArrayList pluginsInCategory; + pluginsInCategory = MainApp.getSpecificPluginsListByInterface(pluginInterface); + + return this.determineActivePlugin(pluginsInCategory, pluginType); + } + + private T determineActivePlugin(int pluginType) { + ArrayList pluginsInCategory; + pluginsInCategory = MainApp.getSpecificPluginsList(pluginType); + + return this.determineActivePlugin(pluginsInCategory, pluginType); + } + + /** + * disables the visibility for all fragments of Plugins in the given pluginsInCategory + * with the given PluginType which are not equally named to the Plugin implementing the + * given Plugin Interface. + *

+ * TODO we are casting an interface to PluginBase, which seems to be rather odd, since + * TODO the interface is not implementing PluginBase (this is just avoiding errors through + * TODO conventions. + * + * @param pluginsInCategory + * @param pluginType + * @param + * @return + */ + private T determineActivePlugin(ArrayList pluginsInCategory, + int pluginType) { + T activePlugin = (T) getTheOneEnabledInArray(pluginsInCategory, pluginType); + + if (activePlugin != null) { + this.setFragmentVisiblities(((PluginBase) activePlugin).getName(), + pluginsInCategory, pluginType); + } + + return activePlugin; + } + + private void setFragmentVisiblities(String activePluginName, ArrayList pluginsInCategory, + int pluginType) { if (Config.logConfigBuilder) - log.debug("Selected treatment interface: " + ((PluginBase) activeTreatments).getName()); + log.debug("Selected interface: " + activePluginName); for (PluginBase p : pluginsInCategory) { - if (!p.getName().equals(((PluginBase) activeTreatments).getName())) { - p.setFragmentVisible(PluginBase.TREATMENT, false); + if (!p.getName().equals(activePluginName)) { + p.setFragmentVisible(pluginType, false); } } } @@ -749,14 +744,17 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr } public String getProfileName(long time, boolean customized) { - ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null) { - return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; - } else { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profileSwitch.profileName; + boolean ignoreProfileSwitchEvents = SP.getBoolean(R.string.key_do_not_track_profile_switch, false); + if (!ignoreProfileSwitchEvents) { + ProfileSwitch profileSwitch = getProfileSwitchFromHistory(time); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null) { + return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; + } else { + Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profileSwitch.profileName; + } } } // Unable to determine profile, failover to default @@ -817,4 +815,40 @@ public class ConfigBuilderPlugin implements PluginBase, ConstraintsInterface, Tr } return null; } + + public void disconnectPump(int durationInMinutes) { + getActiveLoop().disconnectTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000L); + getCommandQueue().tempBasalPercent(0, durationInMinutes, true, new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); + } + } + }); + if (getActivePump().getPumpDescription().isExtendedBolusCapable && isInHistoryExtendedBoluslInProgress()) { + getCommandQueue().cancelExtended(new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.extendedbolusdeliveryerror)); + } + } + }); + } + NSUpload.uploadOpenAPSOffline(durationInMinutes); + } + + public void suspendLoop(int durationInMinutes) { + getActiveLoop().suspendTo(System.currentTimeMillis() + durationInMinutes * 60 * 1000); + getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); + } + } + }); + NSUpload.uploadOpenAPSOffline(durationInMinutes); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java index e4eef9ff2f..14255a28e1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsObjectives/ObjectivesFragment.java @@ -15,7 +15,6 @@ import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +24,7 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.utils.FabricPrivacy; public class ObjectivesFragment extends Fragment { private static Logger log = LoggerFactory.getLogger(ObjectivesFragment.class); @@ -208,7 +208,7 @@ public class ObjectivesFragment extends Fragment { return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java index 42f50d52dd..ef30a0ebb9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java @@ -130,7 +130,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface { if (profile == null) return absoluteRate; if (absoluteRate < 0) absoluteRate = 0d; - Integer maxBasalMult = SP.getInt("openapsama_current_basal_safety_multiplier", 4); + Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d); Integer maxBasalFromDaily = SP.getInt("openapsama_max_daily_safety_multiplier", 3); // Check percentRate but absolute rate too, because we know real current basal in pump Double origRate = absoluteRate; @@ -168,7 +168,7 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface { if (absoluteRate < 0) absoluteRate = 0d; - Integer maxBasalMult = SP.getInt("openapsama_current_basal_safety_multiplier", 4); + Double maxBasalMult = SP.getDouble("openapsama_current_basal_safety_multiplier", 4d); Integer maxBasalFromDaily = SP.getInt("openapsama_max_daily_safety_multiplier", 3); // Check percentRate but absolute rate too, because we know real current basal in pump Double origRate = absoluteRate; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java index a5c00aab7f..8a253af7c2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Food/FoodFragment.java @@ -18,7 +18,6 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -33,6 +32,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.Food; import info.nightscout.androidaps.events.EventFoodDatabaseChanged; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SpinnerHelper; @@ -130,7 +130,7 @@ public class FoodFragment extends SubscriberFragment { filterData(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java index f9a9ce38fc..a171d646e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Insulin/InsulinFragment.java @@ -7,11 +7,11 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.utils.FabricPrivacy; /** * Created by mike on 17.04.2017. @@ -37,7 +37,7 @@ public class InsulinFragment extends Fragment { return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java index c891f60d49..83f71c2430 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java @@ -41,19 +41,19 @@ import info.nightscout.utils.DateUtil; public class IobCobCalculatorPlugin implements PluginBase { private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class); - private static LongSparseArray iobTable = new LongSparseArray<>(); // oldest at index 0 - private static LongSparseArray autosensDataTable = new LongSparseArray<>(); // oldest at index 0 - private static LongSparseArray basalDataTable = new LongSparseArray<>(); // oldest at index 0 + private LongSparseArray iobTable = new LongSparseArray<>(); // oldest at index 0 + private LongSparseArray autosensDataTable = new LongSparseArray<>(); // oldest at index 0 + private LongSparseArray basalDataTable = new LongSparseArray<>(); // oldest at index 0 - private static volatile List bgReadings = null; // newest at index 0 - private static volatile List bucketed_data = null; + private volatile List bgReadings = null; // newest at index 0 + private volatile List bucketed_data = null; - private static double dia = Constants.defaultDIA; + private double dia = Constants.defaultDIA; - static final Object dataLock = new Object(); + final Object dataLock = new Object(); boolean stopCalculationTrigger = false; - IobCobThread thread = null; + private IobCobThread thread = null; private static IobCobCalculatorPlugin plugin = null; @@ -63,11 +63,11 @@ public class IobCobCalculatorPlugin implements PluginBase { return plugin; } - public static LongSparseArray getAutosensDataTable() { + public LongSparseArray getAutosensDataTable() { return autosensDataTable; } - public static List getBucketedData() { + public List getBucketedData() { return bucketed_data; } @@ -131,12 +131,12 @@ public class IobCobCalculatorPlugin implements PluginBase { return -1; } - private IobCobCalculatorPlugin() { + public IobCobCalculatorPlugin() { MainApp.bus().register(this); } @Nullable - public static List getBucketedData(long fromTime) { + public List getBucketedData(long fromTime) { //log.debug("Locking getBucketedData"); synchronized (dataLock) { if (bucketed_data == null) { @@ -154,7 +154,7 @@ public class IobCobCalculatorPlugin implements PluginBase { return null; } - private static int indexNewerThan(long time) { + private int indexNewerThan(long time) { for (int index = 0; index < bucketed_data.size(); index++) { if (bucketed_data.get(index).date < time) return index - 1; @@ -169,9 +169,9 @@ public class IobCobCalculatorPlugin implements PluginBase { return rouded; } - void loadBgData() { - bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)), false); - log.debug("BG data loaded. Size: " + bgReadings.size()); + void loadBgData(long start) { + bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (start - 60 * 60 * 1000L * (24 + dia)), false); + log.debug("BG data loaded. Size: " + bgReadings.size() + " Start date: " + DateUtil.dateAndTimeString(start)); } private boolean isAbout5minData() { @@ -332,13 +332,13 @@ public class IobCobCalculatorPlugin implements PluginBase { return getBGDataFrom; } - public static IobTotal calculateFromTreatmentsAndTempsSynchronized(long time) { + public IobTotal calculateFromTreatmentsAndTempsSynchronized(long time) { synchronized (dataLock) { return calculateFromTreatmentsAndTemps(time); } } - public static IobTotal calculateFromTreatmentsAndTemps(long time) { + public IobTotal calculateFromTreatmentsAndTemps(long time) { long now = System.currentTimeMillis(); time = roundUpTime(time); if (time < now && iobTable.get(time) != null) { @@ -373,7 +373,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } @Nullable - private static Long findPreviousTimeFromBucketedData(long time) { + private Long findPreviousTimeFromBucketedData(long time) { if (bucketed_data == null) return null; for (int index = 0; index < bucketed_data.size(); index++) { @@ -383,7 +383,7 @@ public class IobCobCalculatorPlugin implements PluginBase { return null; } - public static BasalData getBasalData(long time) { + public BasalData getBasalData(long time) { long now = System.currentTimeMillis(); time = roundUpTime(time); BasalData retval = basalDataTable.get(time); @@ -409,7 +409,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } @Nullable - public static AutosensData getAutosensData(long time) { + public AutosensData getAutosensData(long time) { synchronized (dataLock) { long now = System.currentTimeMillis(); if (time > now) @@ -434,7 +434,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } @Nullable - public static AutosensData getLastAutosensDataSynchronized(String reason) { + public AutosensData getLastAutosensDataSynchronized(String reason) { synchronized (dataLock) { return getLastAutosensData(reason); } @@ -442,7 +442,7 @@ public class IobCobCalculatorPlugin implements PluginBase { @Nullable - public static AutosensData getLastAutosensData(String reason) { + public AutosensData getLastAutosensData(String reason) { if (autosensDataTable.size() < 1) { log.debug("AUTOSENSDATA null: autosensDataTable empty (" + reason + ")"); return null; @@ -467,7 +467,7 @@ public class IobCobCalculatorPlugin implements PluginBase { } } - public static IobTotal[] calculateIobArrayInDia() { + public IobTotal[] calculateIobArrayInDia() { Profile profile = MainApp.getConfigBuilder().getProfile(); // predict IOB out to DIA plus 30m long time = System.currentTimeMillis(); @@ -484,7 +484,7 @@ public class IobCobCalculatorPlugin implements PluginBase { return array; } - public static IobTotal[] calculateIobArrayForSMB() { + public IobTotal[] calculateIobArrayForSMB() { Profile profile = MainApp.getConfigBuilder().getProfile(); // predict IOB out to DIA plus 30m long time = System.currentTimeMillis(); @@ -501,7 +501,7 @@ public class IobCobCalculatorPlugin implements PluginBase { return array; } - public static AutosensResult detectSensitivityWithLock(long fromTime, long toTime) { + public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) { synchronized (dataLock) { return detectSensitivity(fromTime, toTime); } @@ -521,13 +521,21 @@ public class IobCobCalculatorPlugin implements PluginBase { @Subscribe public void onEventAppInitialized(EventAppInitialized ev) { - runCalculation("onEventAppInitialized", true, ev); + if (this != getPlugin()) { + log.debug("Ignoring event for non default instance"); + return; + } + runCalculation("onEventAppInitialized", System.currentTimeMillis(), true, ev); } @Subscribe public void onEventNewBG(EventNewBG ev) { + if (this != getPlugin()) { + log.debug("Ignoring event for non default instance"); + return; + } stopCalculation("onEventNewBG"); - runCalculation("onEventNewBG", true, ev); + runCalculation("onEventNewBG", System.currentTimeMillis(), true, ev); } private void stopCalculation(String from) { @@ -541,16 +549,20 @@ public class IobCobCalculatorPlugin implements PluginBase { } } - private void runCalculation(String from, boolean bgDataReload, Event cause) { + public void runCalculation(String from, long start, boolean bgDataReload, Event cause) { log.debug("Starting calculation thread: " + from); if (thread == null || thread.getState() == Thread.State.TERMINATED) { - thread = new IobCobThread(this, from, bgDataReload, cause); + thread = new IobCobThread(this, from, start, bgDataReload, cause); thread.start(); } } @Subscribe public void onNewProfile(EventNewBasalProfile ev) { + if (this != getPlugin()) { + log.debug("Ignoring event for non default instance"); + return; + } if (MainApp.getConfigBuilder() == null) return; // app still initializing Profile profile = MainApp.getConfigBuilder().getProfile(); @@ -566,11 +578,15 @@ public class IobCobCalculatorPlugin implements PluginBase { iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onNewProfile", false, ev); + runCalculation("onNewProfile", System.currentTimeMillis(), false, ev); } @Subscribe public void onEventPreferenceChange(EventPreferenceChange ev) { + if (this != getPlugin()) { + log.debug("Ignoring event for non default instance"); + return; + } if (ev.isChanged(R.string.key_openapsama_autosens_period) || ev.isChanged(R.string.key_age) || ev.isChanged(R.string.key_absorption_maxtime) @@ -581,24 +597,32 @@ public class IobCobCalculatorPlugin implements PluginBase { iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onEventPreferenceChange", false, ev); + runCalculation("onEventPreferenceChange", System.currentTimeMillis(), false, ev); } } @Subscribe public void onEventConfigBuilderChange(EventConfigBuilderChange ev) { + if (this != getPlugin()) { + log.debug("Ignoring event for non default instance"); + return; + } stopCalculation("onEventConfigBuilderChange"); synchronized (dataLock) { log.debug("Invalidating cached data because of configuration change. IOB: " + iobTable.size() + " Autosens: " + autosensDataTable.size() + " records"); iobTable = new LongSparseArray<>(); autosensDataTable = new LongSparseArray<>(); } - runCalculation("onEventConfigBuilderChange", false, ev); + runCalculation("onEventConfigBuilderChange", System.currentTimeMillis(), false, ev); } // When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated @Subscribe public void onEventNewHistoryData(EventNewHistoryData ev) { + if (this != getPlugin()) { + log.debug("Ignoring event for non default instance"); + return; + } //log.debug("Locking onNewHistoryData"); stopCalculation("onEventNewHistoryData"); synchronized (dataLock) { @@ -633,10 +657,18 @@ public class IobCobCalculatorPlugin implements PluginBase { } } } - runCalculation("onEventNewHistoryData", false, ev); + runCalculation("onEventNewHistoryData", System.currentTimeMillis(), false, ev); //log.debug("Releasing onNewHistoryData"); } + public void clearCache() { + synchronized (dataLock) { + log.debug("Clearing cached data."); + iobTable = new LongSparseArray<>(); + autosensDataTable = new LongSparseArray<>(); + } + } + // From https://gist.github.com/IceCreamYou/6ffa1b18c4c8f6aeaad2 // Returns the value at a given percentile in a sorted numeric array. // "Linear interpolation between closest ranks" method diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index 4f63cacf62..ba0475a26f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -21,10 +21,7 @@ import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.queue.QueueThread; - -import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin.getBucketedData; -import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin.oldestDataAvailable; -import static info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin.roundUpTime; +import info.nightscout.utils.DateUtil; /** * Created by mike on 23.01.2018. @@ -37,16 +34,18 @@ public class IobCobThread extends Thread { private IobCobCalculatorPlugin iobCobCalculatorPlugin; private boolean bgDataReload; private String from; + private long start; private PowerManager.WakeLock mWakeLock; - public IobCobThread(IobCobCalculatorPlugin plugin, String from, boolean bgDataReload, Event cause) { + public IobCobThread(IobCobCalculatorPlugin plugin, String from, long start, boolean bgDataReload, Event cause) { super(); this.iobCobCalculatorPlugin = plugin; this.bgDataReload = bgDataReload; this.from = from; this.cause = cause; + this.start = start; PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "iobCobThread"); @@ -68,14 +67,14 @@ public class IobCobThread extends Thread { Object dataLock = iobCobCalculatorPlugin.dataLock; - long oldestTimeWithData = oldestDataAvailable(); + long oldestTimeWithData = iobCobCalculatorPlugin.oldestDataAvailable(); synchronized (dataLock) { if (bgDataReload) { - iobCobCalculatorPlugin.loadBgData(); + iobCobCalculatorPlugin.loadBgData(start); iobCobCalculatorPlugin.createBucketedData(); } - List bucketed_data = getBucketedData(); + List bucketed_data = iobCobCalculatorPlugin.getBucketedData(); LongSparseArray autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable(); if (bucketed_data == null || bucketed_data.size() < 3) { @@ -83,7 +82,7 @@ public class IobCobThread extends Thread { return; } - long prevDataTime = roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date); + long prevDataTime = iobCobCalculatorPlugin.roundUpTime(bucketed_data.get(bucketed_data.size() - 3).date); log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString()); AutosensData previous = autosensDataTable.get(prevDataTime); // start from oldest to be able sub cob @@ -95,7 +94,7 @@ public class IobCobThread extends Thread { } // check if data already exists long bgTime = bucketed_data.get(i).date; - bgTime = roundUpTime(bgTime); + bgTime = iobCobCalculatorPlugin.roundUpTime(bgTime); if (bgTime > System.currentTimeMillis()) continue; Profile profile = MainApp.getConfigBuilder().getProfile(bgTime); @@ -233,6 +232,7 @@ public class IobCobThread extends Thread { previous = autosensData; autosensDataTable.put(bgTime, autosensData); + log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime)); autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio; if (Config.logAutosensData) log.debug(autosensData.log(bgTime)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java index 1550edd192..8050aa7769 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java @@ -184,7 +184,7 @@ public class APSResult { public long getLatestPredictionsTime() { long latest = 0; try { - long startTime = date.getTime(); + long startTime = date != null ? date.getTime() : 0; if (json.has("predBGs")) { JSONObject predBGs = json.getJSONObject("predBGs"); if (predBGs.has("IOB")) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java index 1b696988b2..55038520a4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopFragment.java @@ -9,8 +9,6 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -22,6 +20,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui; import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; +import info.nightscout.utils.FabricPrivacy; public class LoopFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(LoopFragment.class); @@ -53,7 +52,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -71,7 +70,7 @@ public class LoopFragment extends SubscriberFragment implements View.OnClickList } }); thread.start(); - Answers.getInstance().logCustom(new CustomEvent("Loop_Run")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Loop_Run")); break; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java index 2debfa34c5..2fff17a9e7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/LoopPlugin.java @@ -8,7 +8,6 @@ import android.content.Context; import android.content.Intent; import android.support.v4.app.NotificationCompat; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -37,6 +36,7 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; @@ -332,7 +332,7 @@ public class LoopPlugin implements PluginBase { MainApp.getConfigBuilder().applyAPSRequest(resultAfterConstraints, new Callback() { @Override public void run() { - Answers.getInstance().logCustom(new CustomEvent("APSRequest")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("APSRequest")); if (result.enacted || result.success) { lastRun.setByPump = result; lastRun.lastEnact = lastRun.lastAPSRun; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java index 8cd9432f81..a06850e1b1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientInternalFragment.java @@ -18,8 +18,6 @@ import android.widget.CompoundButton; import android.widget.ScrollView; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -33,6 +31,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; public class NSClientInternalFragment extends SubscriberFragment implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { @@ -88,7 +87,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -99,11 +98,11 @@ public class NSClientInternalFragment extends SubscriberFragment implements View switch (view.getId()) { case R.id.nsclientinternal_restart: MainApp.bus().post(new EventNSClientRestart()); - Answers.getInstance().logCustom(new CustomEvent("NSClientRestart")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientRestart")); break; case R.id.nsclientinternal_delivernow: NSClientInternalPlugin.getPlugin().resend("GUI"); - Answers.getInstance().logCustom(new CustomEvent("NSClientDeliverNow")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientDeliverNow")); break; case R.id.nsclientinternal_clearlog: NSClientInternalPlugin.getPlugin().clearLog(); @@ -118,7 +117,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View public void onClick(DialogInterface dialog, int id) { UploadQueue.clearQueue(); updateGUI(); - Answers.getInstance().logCustom(new CustomEvent("NSClientClearQueue")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientClearQueue")); } }); builder.setNegativeButton(getString(R.string.cancel), null); @@ -126,7 +125,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View break; case R.id.nsclientinternal_showqueue: MainApp.bus().post(new EventNSClientNewLog("QUEUE", NSClientInternalPlugin.getPlugin().queue().textList())); - Answers.getInstance().logCustom(new CustomEvent("NSClientShowQueue")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientShowQueue")); break; } } @@ -139,7 +138,7 @@ public class NSClientInternalFragment extends SubscriberFragment implements View NSClientInternalPlugin.getPlugin().paused = isChecked; MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); updateGUI(); - Answers.getInstance().logCustom(new CustomEvent("NSClientPause")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause")); break; case R.id.nsclientinternal_autoscroll: SP.putBoolean(R.string.key_nsclientinternal_autoscroll, isChecked); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java index 1ef71c2f75..4085849675 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/services/NSClientService.java @@ -9,7 +9,7 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.PowerManager; -import com.crashlytics.android.Crashlytics; + import com.google.common.base.Charsets; import com.google.common.hash.Hashing; import com.j256.ormlite.dao.CloseableIterator; @@ -62,6 +62,7 @@ import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotificati import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SP; import io.socket.client.IO; import io.socket.client.Socket; @@ -123,7 +124,7 @@ public class NSClientService extends Service { @Override public void onDestroy() { super.onDestroy(); - mWakeLock.release(); + if (mWakeLock.isHeld()) mWakeLock.release(); } public class LocalBinder extends Binder { @@ -345,14 +346,14 @@ public class NSClientService extends Service { try { data = (JSONObject) args[0]; } catch (Exception e) { - Crashlytics.log("Wrong Announcement from NS: " + args[0]); + FabricPrivacy.log("Wrong Announcement from NS: " + args[0]); return; } if (Config.detailedLog) try { MainApp.bus().post(new EventNSClientNewLog("ANNOUNCEMENT", data.has("message") ? data.getString("message") : "received")); } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } BroadcastAnnouncement.handleAnnouncement(data, getApplicationContext()); log.debug(data.toString()); @@ -381,7 +382,7 @@ public class NSClientService extends Service { try { data = (JSONObject) args[0]; } catch (Exception e) { - Crashlytics.log("Wrong alarm from NS: " + args[0]); + FabricPrivacy.log("Wrong alarm from NS: " + args[0]); return; } BroadcastAlarm.handleAlarm(data, getApplicationContext()); @@ -409,7 +410,7 @@ public class NSClientService extends Service { try { data = (JSONObject) args[0]; } catch (Exception e) { - Crashlytics.log("Wrong Urgent alarm from NS: " + args[0]); + FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]); return; } if (Config.detailedLog) @@ -434,7 +435,7 @@ public class NSClientService extends Service { try { data = (JSONObject) args[0]; } catch (Exception e) { - Crashlytics.log("Wrong Urgent alarm from NS: " + args[0]); + FabricPrivacy.log("Wrong Urgent alarm from NS: " + args[0]); return; } if (Config.detailedLog) @@ -665,7 +666,7 @@ public class NSClientService extends Service { } //MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "onDataUpdate end"); } finally { - wakeLock.release(); + if (wakeLock.isHeld()) wakeLock.release(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java index 66d3ab2b96..7f6df8466d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/DetermineBasalAdapterAMAJS.java @@ -206,12 +206,13 @@ public class DetermineBasalAdapterAMAJS { mProfile.put("carb_ratio", profile.getIc()); mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units)); mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3)); - mProfile.put("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4)); + mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d)); mProfile.put("skip_neutral_temps", true); mProfile.put("current_basal", basalrate); mProfile.put("temptargetSet", tempTargetSet); mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true)); - mProfile.put("min_5m_carbimpact", SP.getInt("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact)); + //TODO: align with max-absorption model in AMA sensitivity + mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact)); if (units.equals(Constants.MMOL)) { mProfile.put("out_units", "mmol/L"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java index b35ebe25a6..9c9ad7d222 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAFragment.java @@ -9,8 +9,6 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -24,6 +22,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnClickListener { @@ -63,7 +62,7 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -74,7 +73,7 @@ public class OpenAPSAMAFragment extends SubscriberFragment implements View.OnCli switch (view.getId()) { case R.id.openapsma_run: OpenAPSAMAPlugin.getPlugin().invoke("OpenAPSAMA button"); - Answers.getInstance().logCustom(new CustomEvent("OpenAPS_AMA_Run")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_AMA_Run")); break; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java index 14d5396817..bfe4fedf1f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSAMA/OpenAPSAMAPlugin.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.Date; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -18,6 +17,7 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; @@ -26,11 +26,10 @@ import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; import info.nightscout.utils.DateUtil; -import info.nightscout.utils.NSUpload; +import info.nightscout.utils.HardLimits; import info.nightscout.utils.Profiler; import info.nightscout.utils.Round; import info.nightscout.utils.SP; -import info.nightscout.utils.ToastUtils; /** * Created by mike on 05.08.2016. @@ -148,6 +147,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); Profile profile = MainApp.getConfigBuilder().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getActivePump(); if (profile == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected))); @@ -183,7 +183,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { Date start = new Date(); Date startPart = new Date(); - IobTotal[] iobArray = IobCobCalculatorPlugin.calculateIobArrayInDia(); + IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayInDia(); Profiler.log(log, "calculateIobArrayInDia()", startPart); startPart = new Date(); @@ -192,35 +192,37 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob); - minBg = verifyHardLimits(minBg, "minBg", Constants.VERY_HARD_LIMIT_MIN_BG[0], Constants.VERY_HARD_LIMIT_MIN_BG[1]); - maxBg = verifyHardLimits(maxBg, "maxBg", Constants.VERY_HARD_LIMIT_MAX_BG[0], Constants.VERY_HARD_LIMIT_MAX_BG[1]); - targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]); + minBg = HardLimits.verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); + maxBg = HardLimits.verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]); + targetBg = HardLimits.verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]); boolean isTempTarget = false; TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { isTempTarget = true; - minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); - maxBg = verifyHardLimits(tempTarget.high, "maxBg", Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); - targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); + minBg = HardLimits.verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); + maxBg = HardLimits.verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); + targetBg = HardLimits.verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); } - maxIob = verifyHardLimits(maxIob, "maxIob", 0, 7); - maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, 10); + maxIob = HardLimits.verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA()); + maxBasal = HardLimits.verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); - if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return; - if (!checkOnlyHardLimits(profile.getIc(Profile.secondsFromMidnight()), "carbratio", 2, 100)) + if (!HardLimits.checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", 2, 900)) + if (!HardLimits.checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return; - if (!checkOnlyHardLimits(ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), "current_basal", 0.01, 5)) + if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + return; + if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, HardLimits.maxBasal())) + return; + if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; startPart = new Date(); if (MainApp.getConfigBuilder().isAMAModeEnabled()) { - lastAutosensResult = IobCobCalculatorPlugin.detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); + lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); } else { lastAutosensResult = new AutosensResult(); } @@ -272,24 +274,4 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface { //deviceStatus.suggested = determineBasalResultAMA.json; } - // safety checks - public static boolean checkOnlyHardLimits(Double value, String valueName, double lowLimit, double highLimit) { - return value.equals(verifyHardLimits(value, valueName, lowLimit, highLimit)); - } - - public static Double verifyHardLimits(Double value, String valueName, double lowLimit, double highLimit) { - Double newvalue = value; - if (newvalue < lowLimit || newvalue > highLimit) { - newvalue = Math.max(newvalue, lowLimit); - newvalue = Math.min(newvalue, highLimit); - String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), valueName); - msg += ".\n"; - msg += String.format(MainApp.sResources.getString(R.string.openapsma_valuelimitedto), value, newvalue); - log.error(msg); - NSUpload.uploadError(msg); - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); - } - return newvalue; - } - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java index 1183a99e67..6b8cb9d0aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAFragment.java @@ -9,8 +9,6 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -22,6 +20,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClickListener { @@ -57,7 +56,7 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -68,7 +67,7 @@ public class OpenAPSMAFragment extends SubscriberFragment implements View.OnClic switch (view.getId()) { case R.id.openapsma_run: OpenAPSMAPlugin.getPlugin().invoke("OpenAPSMA button"); - Answers.getInstance().logCustom(new CustomEvent("OpenAPS_MA_Run")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_MA_Run")); break; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java index 3119a17a96..adb18491a4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSMA/OpenAPSMAPlugin.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.Date; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -18,19 +17,21 @@ import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.APSInterface; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Loop.APSResult; import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.HardLimits; import info.nightscout.utils.Profiler; import info.nightscout.utils.Round; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; -import static info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin.checkOnlyHardLimits; -import static info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin.verifyHardLimits; +import static info.nightscout.utils.HardLimits.checkOnlyHardLimits; +import static info.nightscout.utils.HardLimits.verifyHardLimits; /** * Created by mike on 05.08.2016. @@ -147,6 +148,7 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); Profile profile = MainApp.getConfigBuilder().getProfile(); + PumpInterface pump = ConfigBuilderPlugin.getActivePump(); if (profile == null) { MainApp.bus().post(new EventOpenAPSUpdateResultGui(MainApp.instance().getString(R.string.noprofileselected))); @@ -195,26 +197,29 @@ public class OpenAPSMAPlugin implements PluginBase, APSInterface { maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob); Profiler.log(log, "MA data gathering", start); - minBg = verifyHardLimits(minBg, "minBg", Constants.VERY_HARD_LIMIT_MIN_BG[0], Constants.VERY_HARD_LIMIT_MIN_BG[1]); - maxBg = verifyHardLimits(maxBg, "maxBg", Constants.VERY_HARD_LIMIT_MAX_BG[0], Constants.VERY_HARD_LIMIT_MAX_BG[1]); - targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]); + minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); + maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]); + targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]); TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { - minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); - maxBg = verifyHardLimits(tempTarget.high, "maxBg", Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); - targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); + minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); + maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); + targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); } - maxIob = verifyHardLimits(maxIob, "maxIob", 0, 7); - maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, 10); + maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobAMA()); + maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); - if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return; - if (!checkOnlyHardLimits(profile.getIc(), "carbratio", 2, 100)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", 2, 900)) + if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; - if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return; - if (!checkOnlyHardLimits(ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), "current_basal", 0.01, 5)) + if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) + return; + if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) + return; + if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, HardLimits.maxBasal())) + return; + if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; start = new Date(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java index 57c879a5cd..5ec19adfe8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java @@ -230,7 +230,7 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("carb_ratio", profile.getIc()); mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units)); mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3)); - mProfile.put("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4)); + mProfile.put("current_basal_safety_multiplier", SP.getDouble("openapsama_current_basal_safety_multiplier", 4d)); mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity); mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity); @@ -241,7 +241,8 @@ public class DetermineBasalAdapterSMBJS { mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target); mProfile.put("maxCOB", SMBDefaults.maxCOB); mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps); - mProfile.put("min_5m_carbimpact", SP.getInt("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));; + //TODO: align with max-absorption model in AMA sensitivity + mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));; mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap); mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false)); mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java index ef515c68f2..6c720adc48 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java @@ -8,7 +8,6 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -22,6 +21,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JSONFormatter; public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnClickListener { @@ -66,7 +66,7 @@ public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnCli switch (view.getId()) { case R.id.openapsma_run: OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button"); - Answers.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run")); break; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java index f056a9c607..c992f0e739 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.Date; import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; @@ -27,6 +26,7 @@ import info.nightscout.androidaps.plugins.Loop.ScriptReader; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateResultGui; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.HardLimits; import info.nightscout.utils.NSUpload; import info.nightscout.utils.Profiler; import info.nightscout.utils.Round; @@ -188,7 +188,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { Date start = new Date(); Date startPart = new Date(); - IobTotal[] iobArray = IobCobCalculatorPlugin.calculateIobArrayForSMB(); + IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(); Profiler.log(log, "calculateIobArrayInDia()", startPart); startPart = new Date(); @@ -197,34 +197,34 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { maxIob = MainApp.getConfigBuilder().applyMaxIOBConstraints(maxIob); - minBg = verifyHardLimits(minBg, "minBg", Constants.VERY_HARD_LIMIT_MIN_BG[0], Constants.VERY_HARD_LIMIT_MIN_BG[1]); - maxBg = verifyHardLimits(maxBg, "maxBg", Constants.VERY_HARD_LIMIT_MAX_BG[0], Constants.VERY_HARD_LIMIT_MAX_BG[1]); - targetBg = verifyHardLimits(targetBg, "targetBg", Constants.VERY_HARD_LIMIT_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TARGET_BG[1]); + minBg = verifyHardLimits(minBg, "minBg", HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1]); + maxBg = verifyHardLimits(maxBg, "maxBg", HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1]); + targetBg = verifyHardLimits(targetBg, "targetBg", HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1]); boolean isTempTarget = false; TempTarget tempTarget = MainApp.getConfigBuilder().getTempTargetFromHistory(System.currentTimeMillis()); if (tempTarget != null) { isTempTarget = true; - minBg = verifyHardLimits(tempTarget.low, "minBg", Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); - maxBg = verifyHardLimits(tempTarget.high, "maxBg", Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0], Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); - targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], Constants.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); + minBg = verifyHardLimits(tempTarget.low, "minBg", HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]); + maxBg = verifyHardLimits(tempTarget.high, "maxBg", HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]); + targetBg = verifyHardLimits((tempTarget.low + tempTarget.high) / 2, "targetBg", HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1]); } - maxIob = verifyHardLimits(maxIob, "maxIob", 0, 7); - maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, 10); + maxIob = verifyHardLimits(maxIob, "maxIob", 0, HardLimits.maxIobSMB()); + maxBasal = verifyHardLimits(maxBasal, "max_basal", 0.1, HardLimits.maxBasal()); - if (!checkOnlyHardLimits(profile.getDia(), "dia", 2, 7)) return; - if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", 2, 100)) + if (!checkOnlyHardLimits(profile.getDia(), "dia", HardLimits.MINDIA, HardLimits.MAXDIA)) return; + if (!checkOnlyHardLimits(profile.getIc(profile.secondsFromMidnight()), "carbratio", HardLimits.MINIC, HardLimits.MAXIC)) return; - if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", 2, 900)) + if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf().doubleValue(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) return; - if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, 10)) return; - if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, 5)) return; + if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.1, HardLimits.maxBasal())) return; + if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) return; startPart = new Date(); if (MainApp.getConfigBuilder().isAMAModeEnabled()) { - lastAutosensResult = IobCobCalculatorPlugin.detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); + lastAutosensResult = IobCobCalculatorPlugin.getPlugin().detectSensitivityWithLock(IobCobCalculatorPlugin.oldestDataAvailable(), System.currentTimeMillis()); } else { lastAutosensResult = new AutosensResult(); } @@ -288,9 +288,9 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { if (newvalue < lowLimit || newvalue > highLimit) { newvalue = Math.max(newvalue, lowLimit); newvalue = Math.min(newvalue, highLimit); - String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), valueName); + String msg = String.format(MainApp.sResources.getString(R.string.valueoutofrange), valueName); msg += ".\n"; - msg += String.format(MainApp.sResources.getString(R.string.openapsma_valuelimitedto), value, newvalue); + msg += String.format(MainApp.sResources.getString(R.string.valuelimitedto), value, newvalue); log.error(msg); NSUpload.uploadError(msg); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/SMBDefaults.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/SMBDefaults.java index a7e690ce79..0ce8d2bb94 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/SMBDefaults.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/SMBDefaults.java @@ -40,7 +40,7 @@ public class SMBDefaults { public final static boolean skip_neutral_temps = true; // ***** default false in oref1 ***** if true, don't set neutral temps // unsuspend_if_no_temp:false // if true, pump will un-suspend after a zero temp finishes // bolussnooze_dia_divisor:2 // bolus snooze decays after 1/2 of DIA - public final static int min_5m_carbimpact = 8; // mg/dL per 5m (8 mg/dL/5m corresponds to 24g/hr at a CSF of 4 mg/dL/g (x/5*60/4)) + public final static double min_5m_carbimpact = 8d; // mg/dL per 5m (8 mg/dL/5m corresponds to 24g/hr at a CSF of 4 mg/dL/g (x/5*60/4)) public final static int remainingCarbsCap = 90; // max carbs we'll assume will absorb over 4h if we don't yet see carb absorption // WARNING: use SMB with caution: it can and will automatically bolus up to max_iob worth of extra insulin // enableUAM:true // enable detection of unannounced meal carb absorption 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 index d5053c9317..f0ccdd9809 100644 --- 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 @@ -11,7 +11,6 @@ import android.view.Window; import android.view.WindowManager; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import org.slf4j.Logger; @@ -24,6 +23,7 @@ import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.GlucoseStatus; import info.nightscout.androidaps.data.Profile; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; import info.nightscout.utils.XdripCalibrations; @@ -88,7 +88,7 @@ public class CalibrationDialog extends DialogFragment implements View.OnClickLis final Double bg = SafeParse.stringToDouble(bgNumber.getText()); XdripCalibrations.confirmAndSendCalibration(bg, context); dismiss(); - Answers.getInstance().logCustom(new CustomEvent("Calibration")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Calibration")); break; case R.id.cancel: dismiss(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java index f11283c029..7d45c35792 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorDialog.java @@ -19,6 +19,7 @@ import info.nightscout.androidaps.Services.AlarmSoundService; public class ErrorDialog extends DialogFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(ErrorDialog.class); + Button muteButton; Button okButton; TextView statusView; ErrorHelperActivity helperActivity; @@ -52,14 +53,14 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener Bundle savedInstanceState) { getDialog().setTitle(title); View view = inflater.inflate(R.layout.overview_error_dialog, container, false); + muteButton = (Button) view.findViewById(R.id.overview_error_mute); okButton = (Button) view.findViewById(R.id.overview_error_ok); statusView = (TextView) view.findViewById(R.id.overview_error_status); + muteButton.setOnClickListener(this); okButton.setOnClickListener(this); setCancelable(false); - Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); - alarm.putExtra("soundid", soundId); - MainApp.instance().startService(alarm); + startAlarm(); return view; } @@ -77,13 +78,16 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener if (helperActivity != null) { helperActivity.finish(); } - Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); - MainApp.instance().stopService(alarm); + stopAlarm(); } @Override public void onClick(View view) { switch (view.getId()) { + case R.id.overview_error_mute: + log.debug("Error dialog mute button pressed"); + stopAlarm(); + break; case R.id.overview_error_ok: log.debug("Error dialog ok button pressed"); dismiss(); @@ -91,4 +95,14 @@ public class ErrorDialog extends DialogFragment implements View.OnClickListener } } + private void startAlarm() { + Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); + alarm.putExtra("soundid", soundId); + MainApp.instance().startService(alarm); + } + + private void stopAlarm() { + Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); + MainApp.instance().stopService(alarm); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java index 259c9c76eb..90cf9aecd5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/ErrorHelperActivity.java @@ -3,6 +3,10 @@ package info.nightscout.androidaps.plugins.Overview.Dialogs; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import info.nightscout.androidaps.R; +import info.nightscout.utils.NSUpload; +import info.nightscout.utils.SP; + public class ErrorHelperActivity extends AppCompatActivity { public ErrorHelperActivity() { super(); @@ -17,5 +21,9 @@ public class ErrorHelperActivity extends AppCompatActivity { errorDialog.setSound(getIntent().getIntExtra("soundid", 0)); errorDialog.setTitle(getIntent().getStringExtra("title")); errorDialog.show(this.getSupportFragmentManager(), "Error"); + + if (SP.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) { + NSUpload.uploadError(getIntent().getStringExtra("status")); + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java new file mode 100644 index 0000000000..15e93816bd --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java @@ -0,0 +1,329 @@ +package info.nightscout.androidaps.plugins.Overview.Dialogs; + +import android.content.Context; +import android.os.Bundle; +import android.os.HandlerThread; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.text.Editable; +import android.text.Html; +import android.text.TextWatcher; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.TextView; + +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; +import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout; +import com.wdullaer.materialdatetimepicker.time.TimePickerDialog; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DecimalFormat; +import java.util.Calendar; +import java.util.Date; + +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.Loop.APSResult; +import info.nightscout.androidaps.plugins.Loop.LoopPlugin; +import info.nightscout.androidaps.plugins.OpenAPSSMB.DetermineBasalResultSMB; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.NumberPicker; +import info.nightscout.utils.SP; +import info.nightscout.utils.SafeParse; +import info.nightscout.utils.ToastUtils; + +public class NewCarbsDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener { + private static Logger log = LoggerFactory.getLogger(NewCarbsDialog.class); + + private EditText foodText; + private NumberPicker editCarbs; + + private TextView dateButton; + private TextView timeButton; + + private Date initialEventTime; + private Date eventTime; + + private Button fav1Button; + private Button fav2Button; + private Button fav3Button; + + private static final double FAV1_DEFAULT = 5; + private static final double FAV2_DEFAULT = 10; + private static final double FAV3_DEFAULT = 20; + + private CheckBox suspendLoopCheckbox; + private CheckBox startActivityTTCheckbox; + + private Integer maxCarbs; + + //one shot guards + private boolean accepted; + private boolean okClicked; + + public NewCarbsDialog() { + HandlerThread mHandlerThread = new HandlerThread(NewCarbsDialog.class.getSimpleName()); + mHandlerThread.start(); + } + + final private TextWatcher textWatcher = new TextWatcher() { + @Override + public void afterTextChanged(Editable s) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + validateInputs(); + } + }; + + private void validateInputs() { + Integer carbs = SafeParse.stringToInt(editCarbs.getText()); + if (carbs > maxCarbs) { + editCarbs.setValue(0d); + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.carbsconstraintapplied)); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.overview_newcarbs_dialog, container, false); + + view.findViewById(R.id.ok).setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); + + getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); + getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + + maxCarbs = MainApp.getConfigBuilder().applyCarbsConstraints(Constants.carbsOnlyForCheckLimit); + + foodText = view.findViewById(R.id.newcarb_food); + + editCarbs = view.findViewById(R.id.newcarb_carbsamount); + + editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher); + + startActivityTTCheckbox = view.findViewById(R.id.newcarbs_activity_tt); + + dateButton = view.findViewById(R.id.newcarbs_eventdate); + timeButton = view.findViewById(R.id.newcarb_eventtime); + + initialEventTime = new Date(); + eventTime = new Date(initialEventTime.getTime()); + dateButton.setText(DateUtil.dateString(eventTime)); + timeButton.setText(DateUtil.timeString(eventTime)); + dateButton.setOnClickListener(this); + timeButton.setOnClickListener(this); + +// TODO prefilling carbs, maybe +// TODO maybe update suggested carbs to target TT when checked +// APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult(); +// if (lastAPSResult != null && lastAPSResult instanceof DetermineBasalResultSMB && ((DetermineBasalResultSMB) lastAPSResult).carbsReq > 0) { +// editCarbs.setValue(((DetermineBasalResultSMB) lastAPSResult).carbsReq); +// } + + fav1Button = view.findViewById(R.id.newcarbs_plus1); + fav1Button.setOnClickListener(this); + fav1Button.setText("+" + SP.getString(MainApp.gs(R.string.key_carbs_button_increment_1), String.valueOf(FAV1_DEFAULT))); + fav2Button = view.findViewById(R.id.newcarbs_plus2); + fav2Button.setOnClickListener(this); + fav2Button.setText("+" + SP.getString(MainApp.gs(R.string.key_carbs_button_increment_2), String.valueOf(FAV2_DEFAULT))); + fav3Button = view.findViewById(R.id.newcarbs_plus3); + fav3Button.setOnClickListener(this); + fav3Button.setText("+" + SP.getString(MainApp.gs(R.string.key_carbs_button_increment_3), String.valueOf(FAV3_DEFAULT))); + + suspendLoopCheckbox = view.findViewById(R.id.newcarbs_suspend_loop); + + setCancelable(true); + getDialog().setCanceledOnTouchOutside(false); + return view; + } + + @Override + public synchronized void onClick(View view) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(eventTime); + switch (view.getId()) { + case R.id.ok: + submit(); + break; + case R.id.cancel: + dismiss(); + break; + case R.id.newcarbs_eventdate: + DatePickerDialog dpd = DatePickerDialog.newInstance( + this, + calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH), + calendar.get(Calendar.DAY_OF_MONTH) + ); + dpd.setThemeDark(true); + dpd.dismissOnPause(true); + dpd.show(getActivity().getFragmentManager(), "Datepickerdialog"); + break; + case R.id.newcarb_eventtime: + TimePickerDialog tpd = TimePickerDialog.newInstance( + this, + calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE), + DateFormat.is24HourFormat(getActivity()) + ); + tpd.setThemeDark(true); + tpd.dismissOnPause(true); + tpd.show(getActivity().getFragmentManager(), "Timepickerdialog"); + break; + case R.id.newcarbs_plus1: + editCarbs.setValue(editCarbs.getValue() + + SP.getDouble(MainApp.gs(R.string.key_carbs_button_increment_1), FAV1_DEFAULT)); + validateInputs(); + break; + case R.id.newcarbs_plus2: + editCarbs.setValue(editCarbs.getValue() + + SP.getDouble(MainApp.gs(R.string.key_carbs_button_increment_2), FAV2_DEFAULT)); + validateInputs(); + break; + case R.id.newcarbs_plus3: + editCarbs.setValue(editCarbs.getValue() + + SP.getDouble(MainApp.gs(R.string.key_carbs_button_increment_3), FAV3_DEFAULT)); + validateInputs(); + break; + } + } + + private void submit() { + if (okClicked) { + log.debug("guarding: ok already clicked"); + dismiss(); + return; + } + okClicked = true; + try { + final String food = StringUtils.trimToNull(foodText.getText().toString()); + final Integer carbs = SafeParse.stringToInt(editCarbs.getText()); + Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(carbs); + + String confirmMessage = ""; + if (carbs > 0) + confirmMessage += getString(R.string.carbs) + ": " + "" + carbsAfterConstraints + "g" + ""; + if (!carbsAfterConstraints.equals(carbs)) + confirmMessage += "
" + getString(R.string.carbsconstraintapplied) + ""; + if (suspendLoopCheckbox.isChecked()) { + confirmMessage += "
" + "Loop: " + "" + "Suspend for 30 min"; + } + + double prefTTDuration = SP.getDouble(R.string.key_activity_duration, 90d); + double ttDuration = prefTTDuration > 0 ? prefTTDuration : 90d; + double prefTT = SP.getDouble(R.string.key_activity_target, 140d); + double tt = prefTT > 0 ? prefTT : 140d; + if (startActivityTTCheckbox.isChecked()) { + confirmMessage += "
" + "TT: " + "" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min "; + } + + if (StringUtils.isNoneEmpty(food)) { + confirmMessage += "
" + "Food: " + food; + } + + if (!initialEventTime.equals(eventTime)) { + confirmMessage += "
Time: " + DateUtil.dateAndTimeString(eventTime); + } + + final int finalCarbsAfterConstraints = carbsAfterConstraints; + + final Context context = getContext(); + final AlertDialog.Builder builder = new AlertDialog.Builder(context); + + builder.setTitle(this.getContext().getString(R.string.confirmation)); + if (confirmMessage.startsWith("
")) + confirmMessage = confirmMessage.substring("
".length()); + builder.setMessage(Html.fromHtml(confirmMessage)); + builder.setPositiveButton(getString(R.string.ok), (dialog, id) -> { + synchronized (builder) { + if (accepted) { + log.debug("guarding: already accepted"); + return; + } + accepted = true; + + if (suspendLoopCheckbox.isChecked()) { + final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); + activeloop.suspendTo(System.currentTimeMillis() + 30L * 60 * 1000); + ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + @Override + public void run() { + if (!result.success) { + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); + } + } + }); + } + + if (startActivityTTCheckbox.isChecked()) { + TempTarget tempTarget = new TempTarget(); + tempTarget.date = System.currentTimeMillis(); + tempTarget.durationInMinutes = (int) ttDuration; + tempTarget.reason = "Activity"; + tempTarget.source = Source.USER; + tempTarget.low = (int) tt; + tempTarget.high = (int) tt; + MainApp.getDbHelper().createOrUpdate(tempTarget); + } + + if (finalCarbsAfterConstraints > 0 || food != null) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.date = eventTime.getTime(); + detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION; + detailedBolusInfo.carbs = finalCarbsAfterConstraints; +// detailedBolusInfo.food = food; + detailedBolusInfo.context = context; + detailedBolusInfo.source = Source.USER; + MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + } + } + }); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.show(); + dismiss(); + } catch (Exception e) { + log.error("Unhandled exception", e); + } + } + + @Override + public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { + eventTime.setYear(year - 1900); + eventTime.setMonth(monthOfYear); + eventTime.setDate(dayOfMonth); + dateButton.setText(DateUtil.dateString(eventTime)); + } + + @Override + public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) { + eventTime.setHours(hourOfDay); + eventTime.setMinutes(minute); + eventTime.setSeconds(second); + timeButton.setText(DateUtil.timeString(eventTime)); + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java new file mode 100644 index 0000000000..7c86cde764 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java @@ -0,0 +1,342 @@ +package info.nightscout.androidaps.plugins.Overview.Dialogs; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.HandlerThread; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.text.Editable; +import android.text.Html; +import android.text.TextWatcher; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.TextView; + +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.CustomEvent; +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; +import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout; +import com.wdullaer.materialdatetimepicker.time.TimePickerDialog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DecimalFormat; +import java.util.Calendar; +import java.util.Date; + +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.db.CareportalEvent; +import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.Loop.APSResult; +import info.nightscout.androidaps.plugins.OpenAPSSMB.DetermineBasalResultSMB; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.DateUtil; +import info.nightscout.utils.NumberPicker; +import info.nightscout.utils.SP; +import info.nightscout.utils.SafeParse; +import info.nightscout.utils.ToastUtils; + +public class NewInsulinDialog extends DialogFragment implements OnClickListener, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener { + private static Logger log = LoggerFactory.getLogger(NewInsulinDialog.class); + + private NumberPicker editInsulin; + + private TextView dateButton; + private TextView timeButton; + + private Date initialEventTime; + private Date eventTime; + + private Button plus1Button; + private Button plus2Button; + private Button plus3Button; + + public static final double PLUS1_DEFAULT = 0.5d; + public static final double PLUS2_DEFAULT = 1d; + public static final double PLUS3_DEFAULT = 2d; + + private CheckBox startESMCheckbox; + private CheckBox recordOnlyCheckbox; + + private Double maxInsulin; + + //one shot guards + private boolean accepted; + private boolean okClicked; + + public NewInsulinDialog() { + HandlerThread mHandlerThread = new HandlerThread(NewInsulinDialog.class.getSimpleName()); + mHandlerThread.start(); + } + + final private TextWatcher textWatcher = new TextWatcher() { + @Override + public void afterTextChanged(Editable s) { + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + validateInputs(); + } + }; + + private void validateInputs() { + Double insulin = SafeParse.stringToDouble(editInsulin.getText()); + if (insulin > maxInsulin) { + editInsulin.setValue(0d); + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied)); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.overview_newinsulin_dialog, container, false); + + view.findViewById(R.id.ok).setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); + + getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); + getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + + maxInsulin = MainApp.getConfigBuilder().applyBolusConstraints(Constants.bolusOnlyForCheckLimit); + + editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount); + + editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher); + + dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate); + timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime); + + initialEventTime = new Date(); + eventTime = new Date(initialEventTime.getTime()); + dateButton.setText(DateUtil.dateString(eventTime)); + timeButton.setText(DateUtil.timeString(eventTime)); + dateButton.setOnClickListener(this); + timeButton.setOnClickListener(this); + +/* + // This makes it to easy to just bolus insulinReq, which is almost always too much + APSResult lastAPSResult = ConfigBuilderPlugin.getActiveAPS().getLastAPSResult(); + if (lastAPSResult != null && lastAPSResult instanceof DetermineBasalResultSMB && ((DetermineBasalResultSMB) lastAPSResult).insulinReq > 0) { + editInsulin.setValue(((DetermineBasalResultSMB )lastAPSResult).insulinReq); + } +*/ + + plus1Button = (Button) view.findViewById(R.id.newinsulin_plus05); + plus1Button.setOnClickListener(this); + plus1Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_1), String.valueOf(PLUS1_DEFAULT))); + plus2Button = (Button) view.findViewById(R.id.newinsulin_plus10); + plus2Button.setOnClickListener(this); + plus2Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_2), String.valueOf(PLUS2_DEFAULT))); + plus3Button = (Button) view.findViewById(R.id.newinsulin_plus20); + plus3Button.setOnClickListener(this); + plus3Button.setText("+" + SP.getString(MainApp.gs(R.string.key_insulin_button_increment_3), String.valueOf(PLUS3_DEFAULT))); + + startESMCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_start_eating_soon_tt); + recordOnlyCheckbox = (CheckBox) view.findViewById(R.id.newinsulin_record_only); + recordOnlyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (dateButton != null) dateButton.setEnabled(isChecked); + if (timeButton != null) timeButton.setEnabled(isChecked); + }); + + setCancelable(true); + getDialog().setCanceledOnTouchOutside(false); + return view; + } + + @Override + public synchronized void onClick(View view) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(eventTime); + switch (view.getId()) { + case R.id.ok: + submit(); + break; + case R.id.cancel: + dismiss(); + break; + case R.id.newinsulin_eventdate: + DatePickerDialog dpd = DatePickerDialog.newInstance( + this, + calendar.get(Calendar.YEAR), + calendar.get(Calendar.MONTH), + calendar.get(Calendar.DAY_OF_MONTH) + ); + dpd.setThemeDark(true); + dpd.dismissOnPause(true); + dpd.show(getActivity().getFragmentManager(), "Datepickerdialog"); + break; + case R.id.newinsulin_eventtime: + TimePickerDialog tpd = TimePickerDialog.newInstance( + this, + calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE), + DateFormat.is24HourFormat(getActivity()) + ); + tpd.setThemeDark(true); + tpd.dismissOnPause(true); + tpd.show(getActivity().getFragmentManager(), "Timepickerdialog"); + break; + case R.id.newinsulin_start_eating_soon_tt: + final Profile profile = MainApp.getConfigBuilder().getProfile(); + double tt = SP.getDouble(R.string.key_eatingsoon_target, 0d); + double ttBgAdd = (tt - profile.getTargetLow()) / profile.getIsf(); + editInsulin.setValue(editInsulin.getValue() + (startESMCheckbox.isChecked() ? ttBgAdd : -ttBgAdd)); + break; + case R.id.newinsulin_plus05: + editInsulin.setValue(editInsulin.getValue() + + SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT)); + validateInputs(); + break; + case R.id.newinsulin_plus10: + editInsulin.setValue(editInsulin.getValue() + + SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT)); + validateInputs(); + break; + case R.id.newinsulin_plus20: + editInsulin.setValue(editInsulin.getValue() + + SP.getDouble(MainApp.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT)); + validateInputs(); + break; + } + } + + private void submit() { + if (okClicked){ + log.debug("guarding: ok already clicked"); + dismiss(); + return; + } + okClicked = true; + try { + Double insulin = SafeParse.stringToDouble(editInsulin.getText()); + Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(insulin); + + String confirmMessage = ""; + if (insulin > 0) { + confirmMessage += getString(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""; + if (recordOnlyCheckbox.isChecked()) { + confirmMessage += "
" + "Bolus will be recorded only"; + } + } + + if (!insulinAfterConstraints.equals(insulin)) + confirmMessage += "
" + getString(R.string.bolusconstraintapplied) + ""; + double prefTTDuration = SP.getDouble(R.string.key_eatingsoon_duration, 45d); + double ttDuration = prefTTDuration > 0 ? prefTTDuration : 45d; + double prefTT = SP.getDouble(R.string.key_eatingsoon_target, 80d); + double tt = prefTT > 0 ? prefTT : 80d; + if (startESMCheckbox.isChecked()) { + confirmMessage += "
" + "TT: " + "" + ((int) tt) + "mg/dl for " + ((int) ttDuration) + " min "; + } + + if (!initialEventTime.equals(eventTime)) { + confirmMessage += "
Time: " + DateUtil.dateAndTimeString(eventTime); + } + + final double finalInsulinAfterConstraints = insulinAfterConstraints; + + final Context context = getContext(); + final AlertDialog.Builder builder = new AlertDialog.Builder(context); + + builder.setTitle(this.getContext().getString(R.string.confirmation)); + if (confirmMessage.startsWith("
")) + confirmMessage = confirmMessage.substring("
".length()); + builder.setMessage(Html.fromHtml(confirmMessage)); + builder.setPositiveButton(getString(R.string.ok), (dialog, id) -> { + synchronized (builder) { + if (accepted) { + log.debug("guarding: already accepted"); + return; + } + accepted = true; + + if (startESMCheckbox.isChecked()) { + TempTarget tempTarget = new TempTarget(); + tempTarget.date = System.currentTimeMillis(); + tempTarget.durationInMinutes = (int) ttDuration; + tempTarget.reason = "Eating soon"; + tempTarget.source = Source.USER; + tempTarget.low = (int) tt; + tempTarget.high = (int) tt; + MainApp.getDbHelper().createOrUpdate(tempTarget); + } + + if (finalInsulinAfterConstraints <= 0.01) { + return; + } + + if (recordOnlyCheckbox.isChecked()) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.source = Source.USER; + detailedBolusInfo.date = eventTime.getTime(); + detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; + detailedBolusInfo.insulin = finalInsulinAfterConstraints; + MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + } else { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS; + detailedBolusInfo.insulin = finalInsulinAfterConstraints; + detailedBolusInfo.context = context; + detailedBolusInfo.source = Source.USER; + ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + if (!result.success) { + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.boluserror); + i.putExtra("status", result.comment); + i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); + } + } + }); + Answers.getInstance().logCustom(new CustomEvent("Bolus")); + } + } + }); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.show(); + dismiss(); + } catch (Exception e) { + log.error("Unhandled exception", e); + } + } + + @Override + public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { + eventTime.setYear(year - 1900); + eventTime.setMonth(monthOfYear); + eventTime.setDate(dayOfMonth); + dateButton.setText(DateUtil.dateString(eventTime)); + } + + @Override + public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) { + eventTime.setHours(hourOfDay); + eventTime.setMinutes(minute); + eventTime.setSeconds(second); + timeButton.setText(DateUtil.timeString(eventTime)); + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java index 69fbfdc149..2fd897b3aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewTreatmentDialog.java @@ -16,7 +16,6 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import org.slf4j.Logger; @@ -31,9 +30,9 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; -import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; import info.nightscout.utils.ToastUtils; @@ -176,7 +175,7 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene } else { MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); } - Answers.getInstance().logCustom(new CustomEvent("Bolus")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus")); } } } 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 d74c9caadf..29d23050de 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 @@ -25,7 +25,6 @@ import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -50,6 +49,7 @@ import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; +import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; @@ -57,9 +57,8 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Loop.LoopPlugin; -import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin; -import info.nightscout.androidaps.plugins.OpenAPSMA.events.EventOpenAPSUpdateGui; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; @@ -132,6 +131,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com public void onResume() { super.onResume(); MainApp.bus().register(this); + MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.WIZARD)); } @Override @@ -382,7 +382,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } else { MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); } - Answers.getInstance().logCustom(new CustomEvent("Wizard")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Wizard")); } } } @@ -476,7 +476,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com // COB Double c_cob = 0d; if (cobCheckbox.isChecked()) { - AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensData("Wizard COB"); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Wizard COB"); if(autosensData != null) { c_cob = autosensData.cob; 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 13b81fe8be..773482c20e 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 @@ -3,9 +3,11 @@ package info.nightscout.androidaps.plugins.Overview; import android.annotation.SuppressLint; import android.app.Activity; import android.app.NotificationManager; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; @@ -32,8 +34,6 @@ import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.jjoe64.graphview.GraphView; import com.squareup.otto.Subscribe; @@ -95,6 +95,8 @@ import info.nightscout.androidaps.plugins.NSClientInternal.broadcasts.BroadcastA import info.nightscout.androidaps.plugins.NSClientInternal.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; +import info.nightscout.androidaps.plugins.Overview.Dialogs.NewCarbsDialog; +import info.nightscout.androidaps.plugins.Overview.Dialogs.NewInsulinDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog; import info.nightscout.androidaps.plugins.Overview.activities.QuickWizardListActivity; @@ -103,12 +105,14 @@ import info.nightscout.androidaps.plugins.Overview.events.EventSetWakeLock; import info.nightscout.androidaps.plugins.Overview.graphData.GraphData; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.Overview.notifications.NotificationStore; +import info.nightscout.androidaps.plugins.SourceDexcomG5.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.utils.OKDialog; import info.nightscout.utils.Profiler; @@ -163,10 +167,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, LinearLayoutManager llm; LinearLayout acceptTempLayout; + SingleClickButton acceptTempButton; + SingleClickButton treatmentButton; SingleClickButton wizardButton; SingleClickButton calibrationButton; - SingleClickButton acceptTempButton; + SingleClickButton insulinButton; + SingleClickButton carbsButton; + SingleClickButton cgmButton; SingleClickButton quickWizardButton; CheckBox lockScreen; @@ -257,6 +265,12 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, treatmentButton.setOnClickListener(this); wizardButton = (SingleClickButton) view.findViewById(R.id.overview_wizardbutton); wizardButton.setOnClickListener(this); + insulinButton = (SingleClickButton) view.findViewById(R.id.overview_insulinbutton); + if (insulinButton != null) + insulinButton.setOnClickListener(this); + carbsButton = (SingleClickButton) view.findViewById(R.id.overview_carbsbutton); + if (carbsButton != null) + carbsButton.setOnClickListener(this); acceptTempButton = (SingleClickButton) view.findViewById(R.id.overview_accepttempbutton); if (acceptTempButton != null) acceptTempButton.setOnClickListener(this); @@ -266,6 +280,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, calibrationButton = (SingleClickButton) view.findViewById(R.id.overview_calibrationbutton); if (calibrationButton != null) calibrationButton.setOnClickListener(this); + cgmButton = (SingleClickButton) view.findViewById(R.id.overview_cgmbutton); + if (cgmButton != null) + cgmButton.setOnClickListener(this); acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout); @@ -342,7 +359,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); log.debug("Runtime Exception", e); } @@ -366,7 +383,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, menu.add(MainApp.sResources.getString(R.string.suspendloopfor2h)); menu.add(MainApp.sResources.getString(R.string.suspendloopfor3h)); menu.add(MainApp.sResources.getString(R.string.suspendloopfor10h)); - if (pumpDescription.tempDurationStep <= 30) + if (pumpDescription.tempDurationStep15mAllowed) + menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor15m)); + if (pumpDescription.tempDurationStep30mAllowed) menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor30m)); menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor1h)); menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor2h)); @@ -421,7 +440,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, activeloop.setFragmentVisible(PluginBase.LOOP, false); MainApp.getConfigBuilder().storeSettings(); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { if (!result.success) { @@ -429,7 +448,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); - NSUpload.uploadOpenAPSOffline(60); // upload 60 min, we don;t know real duration + NSUpload.uploadOpenAPSOffline(24 * 60); // upload 24h, we don't know real duration return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) { activeloop.setFragmentEnabled(PluginBase.LOOP, true); @@ -441,7 +460,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) { activeloop.suspendTo(0L); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { + MainApp.getConfigBuilder().getCommandQueue().cancelTempBasal(true, new Callback() { @Override public void run() { if (!result.success) { @@ -452,148 +471,40 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NSUpload.uploadOpenAPSOffline(0); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) { - activeloop.suspendTo(System.currentTimeMillis() + 60L * 60 * 1000); + MainApp.getConfigBuilder().suspendLoop(60); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - NSUpload.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) { - activeloop.suspendTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); + MainApp.getConfigBuilder().suspendLoop(120); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - NSUpload.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) { - activeloop.suspendTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000); + MainApp.getConfigBuilder().suspendLoop(180); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - NSUpload.uploadOpenAPSOffline(180); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) { - activeloop.suspendTo(System.currentTimeMillis() + 10 * 60L * 60 * 1000); + MainApp.getConfigBuilder().suspendLoop(600); + updateGUI("suspendmenu"); + return true; + } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor15m))) { + MainApp.getConfigBuilder().disconnectPump(15); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().cancelTempBasal(true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - NSUpload.uploadOpenAPSOffline(600); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) { - activeloop.disconnectTo(System.currentTimeMillis() + 30L * 60 * 1000); + MainApp.getConfigBuilder().disconnectPump(30); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 30, true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); - } - } - }); - } - NSUpload.uploadOpenAPSOffline(30); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) { - activeloop.disconnectTo(System.currentTimeMillis() + 1 * 60L * 60 * 1000); + MainApp.getConfigBuilder().disconnectPump(60); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 60, true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); - } - } - }); - } - NSUpload.uploadOpenAPSOffline(60); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) { - activeloop.disconnectTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000); + MainApp.getConfigBuilder().disconnectPump(120); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 2 * 60, true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); - } - } - }); - } - NSUpload.uploadOpenAPSOffline(120); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) { - activeloop.disconnectTo(System.currentTimeMillis() + 3 * 60L * 60 * 1000); + MainApp.getConfigBuilder().disconnectPump(180); updateGUI("suspendmenu"); - ConfigBuilderPlugin.getCommandQueue().tempBasalPercent(0, 3 * 60, true, new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror)); - } - } - }); - if (MainApp.getConfigBuilder().getActivePump().getPumpDescription().isExtendedBolusCapable && MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ConfigBuilderPlugin.getCommandQueue().cancelExtended( new Callback() { - @Override - public void run() { - if (!result.success) { - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.extendedbolusdeliveryerror)); - } - } - }); - } - NSUpload.uploadOpenAPSOffline(180); return true; } else if (item.getTitle().equals(MainApp.sResources.getString(R.string.careportal_profileswitch))) { NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); @@ -612,6 +523,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, @Override public void onClick(View v) { + boolean xdrip = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE); + boolean g5 = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginBase.BGSOURCE); + String units = MainApp.getConfigBuilder().getProfileUnits(); + FragmentManager manager = getFragmentManager(); switch (v.getId()) { case R.id.overview_accepttempbutton: @@ -625,13 +540,36 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, wizardDialog.show(manager, "WizardDialog"); break; case R.id.overview_calibrationbutton: - CalibrationDialog calibrationDialog = new CalibrationDialog(); - calibrationDialog.show(manager, "CalibrationDialog"); + if (xdrip) { + CalibrationDialog calibrationDialog = new CalibrationDialog(); + calibrationDialog.show(manager, "CalibrationDialog"); + } else if (g5) { + try { + Intent i = new Intent("com.dexcom.cgm.activities.MeterEntryActivity"); + startActivity(i); + } catch (ActivityNotFoundException e) { + ToastUtils.showToastInUiThread(getActivity(), MainApp.gs(R.string.g5appnotdetected)); + } + } + break; + case R.id.overview_cgmbutton: + if (xdrip) + openCgmApp("com.eveningoutpost.dexdrip"); + else if (g5 && units.equals(Constants.MGDL)) + openCgmApp("com.dexcom.cgm.region5.mgdl"); + else if (g5 && units.equals(Constants.MMOL)) + openCgmApp("com.dexcom.cgm.region5.mmol"); break; case R.id.overview_treatmentbutton: NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog(); treatmentDialogFragment.show(manager, "TreatmentDialog"); break; + case R.id.overview_insulinbutton: + new NewInsulinDialog().show(manager, "InsulinDialog"); + break; + case R.id.overview_carbsbutton: + new NewCarbsDialog().show(manager, "CarbsDialog"); + break; case R.id.overview_pumpstatus: if (ConfigBuilderPlugin.getActivePump().isSuspended() || !ConfigBuilderPlugin.getActivePump().isInitialized()) ConfigBuilderPlugin.getCommandQueue().readStatus("RefreshClicked", null); @@ -658,6 +596,25 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } + public boolean openCgmApp(String packageName) { + PackageManager packageManager = getContext().getPackageManager(); + try { + Intent intent = packageManager.getLaunchIntentForPackage(packageName); + if (intent == null) { + throw new ActivityNotFoundException(); + } + intent.addCategory(Intent.CATEGORY_LAUNCHER); + getContext().startActivity(intent); + return true; + } catch (ActivityNotFoundException e) { + new AlertDialog.Builder(getContext()) + .setMessage(R.string.error_starting_cgm) + .setPositiveButton("OK", null) + .show(); + return false; + } + } + @Override public boolean onLongClick(View v) { switch (v.getId()) { @@ -698,7 +655,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, scheduleUpdateGUI("onClickAcceptTemp"); } }); - Answers.getInstance().logCustom(new CustomEvent("AcceptTemp")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp")); } }); builder.setNegativeButton(getContext().getString(R.string.cancel), null); @@ -814,7 +771,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } }); - Answers.getInstance().logCustom(new CustomEvent("QuickWizard")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("QuickWizard")); } } } @@ -1015,16 +972,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, return; } - double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units)); - double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units)); - - if (lowLineSetting < 1) - lowLineSetting = Profile.fromMgdlToUnits(76d, units); - if (highLineSetting < 1) - highLineSetting = Profile.fromMgdlToUnits(180d, units); - - final double lowLine = lowLineSetting; - final double highLine = highLineSetting; + final double lowLine = OverviewPlugin.getPlugin().determineLowLine(units); + final double highLine = OverviewPlugin.getPlugin().determineHighLine(units); //Start with updating the BG as it is unaffected by loop. // **** BG value **** @@ -1114,14 +1063,26 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } } - // **** Calibration button **** + // **** Calibration & CGM buttons **** + boolean xDripIsBgSource = MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE); + boolean g5IsBgSource = MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class) != null && MainApp.getSpecificPlugin(SourceDexcomG5Plugin.class).isEnabled(PluginBase.BGSOURCE); + boolean bgAvailable = DatabaseHelper.actualBg() != null; if (calibrationButton != null) { - if (MainApp.getSpecificPlugin(SourceXdripPlugin.class) != null && MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && DatabaseHelper.actualBg() != null) { + if ((xDripIsBgSource || g5IsBgSource) && bgAvailable && SP.getBoolean(R.string.key_show_calibration_button, true)) { calibrationButton.setVisibility(View.VISIBLE); } else { calibrationButton.setVisibility(View.GONE); } } + if (cgmButton != null) { + if (xDripIsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) { + cgmButton.setVisibility(View.VISIBLE); + } else if (g5IsBgSource && SP.getBoolean(R.string.key_show_cgm_button, false)) { + cgmButton.setVisibility(View.VISIBLE); + } else { + cgmButton.setVisibility(View.GONE); + } + } final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); String basalText = ""; @@ -1218,15 +1179,40 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, } else quickWizardButton.setVisibility(View.GONE); - // Bolus and calc button - if (pump.isInitialized() && !pump.isSuspended()) { - wizardButton.setVisibility(View.VISIBLE); - treatmentButton.setVisibility(View.VISIBLE); - } else { - wizardButton.setVisibility(View.GONE); - treatmentButton.setVisibility(View.GONE); + // **** Various treatment buttons **** + if (carbsButton != null) { + if (SP.getBoolean(R.string.key_show_carbs_button, true) + && !ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo || + (pump.isInitialized() && !pump.isSuspended())) { + carbsButton.setVisibility(View.VISIBLE); + } else { + carbsButton.setVisibility(View.GONE); + } } + if (pump.isInitialized() && !pump.isSuspended()) { + if (treatmentButton != null) { + if (SP.getBoolean(R.string.key_show_treatment_button, false)) { + treatmentButton.setVisibility(View.VISIBLE); + } else { + treatmentButton.setVisibility(View.GONE); + } + } + if (wizardButton != null) { + if (SP.getBoolean(R.string.key_show_wizard_button, true)) { + wizardButton.setVisibility(View.VISIBLE); + } else { + wizardButton.setVisibility(View.GONE); + } + } + if (insulinButton != null) { + if (SP.getBoolean(R.string.key_show_insulin_button, true)) { + insulinButton.setVisibility(View.VISIBLE); + } else { + insulinButton.setVisibility(View.GONE); + } + } + } // **** BG value **** if (lastBG == null) { //left this here as it seems you want to exit at this point if it is null... @@ -1276,7 +1262,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // cob if (cobView != null) { // view must not exists String cobText = ""; - AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensData("Overview COB"); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Overview COB"); if (autosensData != null) cobText = (int) autosensData.cob + " g"; cobView.setText(cobText); @@ -1362,7 +1348,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, // ------------------ 1st graph Profiler.log(log, from + " - 1st graph - START", updateGUIStart); - final GraphData graphData = new GraphData(bgGraph); + final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin()); // **** In range Area **** graphData.addInRangeArea(fromTime, endTime, lowLine, highLine); @@ -1384,13 +1370,16 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2d); } + // add target line + graphData.addTargetLine(fromTime, toTime); + // **** NOW line **** graphData.addNowLine(now); // ------------------ 2nd graph Profiler.log(log, from + " - 2nd graph - START", updateGUIStart); - final GraphData secondGraphData = new GraphData(iobGraph); + final GraphData secondGraphData = new GraphData(iobGraph, IobCobCalculatorPlugin.getPlugin()); boolean useIobForScale = false; boolean useCobForScale = false; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java index eb31ae66ed..8b276f937d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java @@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.QuickWizard; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.PluginBase; @@ -26,7 +27,6 @@ public class OverviewPlugin implements PluginBase { private static OverviewPlugin overviewPlugin = new OverviewPlugin(); public static OverviewPlugin getPlugin() { - if (overviewPlugin == null) overviewPlugin = new OverviewPlugin(); return overviewPlugin; @@ -92,7 +92,7 @@ public class OverviewPlugin implements PluginBase { @Override public boolean showInList(int type) { - return false; + return true; } @Override @@ -107,7 +107,7 @@ public class OverviewPlugin implements PluginBase { @Override public int getPreferencesId() { - return -1; + return R.xml.pref_overview; } @Override @@ -128,4 +128,34 @@ public class OverviewPlugin implements PluginBase { MainApp.bus().post(new EventRefreshOverview("EventDismissNotification")); } + public double determineHighLine() { + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) { + return bgTargetHigh; + } + return determineHighLine(profile.getUnits()); + } + + public double determineHighLine(String units) { + double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units)); + if (highLineSetting < 1) + highLineSetting = Profile.fromMgdlToUnits(180d, units); + return highLineSetting; + } + + public double determineLowLine() { + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) { + return bgTargetLow; + } + return determineLowLine(profile.getUnits()); + } + + public double determineLowLine(String units) { + double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units)); + if (lowLineSetting < 1) + lowLineSetting = Profile.fromMgdlToUnits(76d, units); + return lowLineSetting; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java index e0fd53a1fd..080dec4bd2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventOverviewBolusProgress.java @@ -16,6 +16,10 @@ public class EventOverviewBolusProgress extends Event { public EventOverviewBolusProgress() { } + public boolean isSMB(){ + return (t != null) && t.isSMB; + } + public static EventOverviewBolusProgress getInstance() { if(eventOverviewBolusProgress == null) { eventOverviewBolusProgress = new EventOverviewBolusProgress(); 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 f6cd2eecdc..02bb1a7b3d 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 @@ -22,12 +22,14 @@ import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ProfileSwitch; +import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.IobCobCalculator.BasalData; import info.nightscout.androidaps.plugins.Loop.APSResult; +import info.nightscout.androidaps.plugins.Loop.LoopPlugin; import info.nightscout.androidaps.plugins.Overview.graphExtensions.AreaGraphSeries; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.Overview.graphExtensions.DoubleDataPoint; @@ -36,6 +38,7 @@ import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLab import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale; import info.nightscout.androidaps.plugins.Overview.graphExtensions.ScaledDataPoint; import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter; +import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.utils.Round; /** @@ -50,9 +53,12 @@ public class GraphData { private String units; private List series = new ArrayList<>(); - public GraphData(GraphView graph) { + private IobCobCalculatorPlugin iobCobCalculatorPlugin; + + public GraphData(GraphView graph, IobCobCalculatorPlugin iobCobCalculatorPlugin) { units = MainApp.getConfigBuilder().getProfileUnits(); this.graph = graph; + this.iobCobCalculatorPlugin = iobCobCalculatorPlugin; } public void addBgReadings(long fromTime, long toTime, double lowLine, double highLine, APSResult apsResult) { @@ -126,7 +132,7 @@ public class GraphData { double lastBaseBasal = 0; double lastTempBasal = 0; for (long time = fromTime; time < toTime; time += 60 * 1000L) { - BasalData basalData = IobCobCalculatorPlugin.getBasalData(time); + BasalData basalData = IobCobCalculatorPlugin.getPlugin().getBasalData(time); double baseBasalValue = basalData.basal; double absoluteLineValue = baseBasalValue; double tempBasalValue = 0; @@ -215,6 +221,54 @@ public class GraphData { addSeries(absoluteBasalsLineSeries); } + public void addTargetLine(long fromTime, long toTime) { + Profile profile = MainApp.getConfigBuilder().getProfile(); + if (profile == null) { + return; + } + + LineGraphSeries targetsSeries; + + Scale targetsScale = new Scale(); + targetsScale.setMultiplier(1); + + List targetsSeriesArray = new ArrayList<>(); + double lastTarget = 0; + + if (LoopPlugin.lastRun != null && LoopPlugin.lastRun.constraintsProcessed != null) { + APSResult apsResult = LoopPlugin.lastRun.constraintsProcessed; + long latestPredictionsTime = apsResult.getLatestPredictionsTime(); + if (latestPredictionsTime > toTime) { + toTime = latestPredictionsTime; + } + } + + for (long time = fromTime; time < toTime; time += 60 * 1000L) { + TempTarget tt = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(time); + double value; + if (tt == null) { + value = (profile.getTargetLow(time) + profile.getTargetHigh(time)) / 2; + } else { + value = (tt.low + tt.high) / 2; + } + if (lastTarget > 0 && lastTarget != value) { + targetsSeriesArray.add(new DataPoint(time, lastTarget)); + } + lastTarget = value; + + targetsSeriesArray.add(new DataPoint(time, value)); + } + + DataPoint[] targets = new DataPoint[targetsSeriesArray.size()]; + targets = targetsSeriesArray.toArray(targets); + targetsSeries = new LineGraphSeries<>(targets); + targetsSeries.setDrawBackground(false); + targetsSeries.setColor(MainApp.sResources.getColor(R.color.tempTargetBackground)); + targetsSeries.setThickness(2); + + addSeries(targetsSeries); + } + public void addTreatments(long fromTime, long endTime) { List filteredTreatments = new ArrayList<>(); @@ -284,7 +338,7 @@ public class GraphData { Scale iobScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - double iob = IobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(time).iob; + double iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(time).iob; if (Math.abs(lastIob - iob) > 0.02) { if (Math.abs(lastIob - iob) > 0.2) iobArray.add(new ScaledDataPoint(time, lastIob, iobScale)); @@ -319,7 +373,7 @@ public class GraphData { Scale cobScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); if (autosensData != null) { int cob = (int) autosensData.cob; if (cob != lastCob) { @@ -366,7 +420,7 @@ public class GraphData { Scale devScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); if (autosensData != null) { int color = Color.BLACK; // "=" if (autosensData.pastSensitivity.equals("C")) color = Color.GRAY; @@ -404,7 +458,7 @@ public class GraphData { Scale ratioScale = new Scale(-1d); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); if (autosensData != null) { ratioArray.add(new ScaledDataPoint(time, autosensData.autosensRatio, ratioScale)); maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio)); @@ -438,7 +492,7 @@ public class GraphData { Scale dsMinScale = new Scale(); for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) { - AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getAutosensData(time); if (autosensData != null) { dsMaxArray.add(new ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale)); dsMinArray.add(new ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationStore.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationStore.java index 1ce92249f7..aa61b48097 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationStore.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/NotificationStore.java @@ -21,8 +21,6 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.Services.AlarmSoundService; -import info.nightscout.androidaps.plugins.Wear.WearPlugin; -//Added by Rumen for snooze time import info.nightscout.utils.SP; /** @@ -44,16 +42,12 @@ public class NotificationStore { } } - public Notification get(int index) { - return store.get(index); - } - - public void add(Notification n) { + public synchronized void add(Notification n) { log.info("Notification received: " + n.text); - for (int i = 0; i < store.size(); i++) { - if (get(i).id == n.id) { - get(i).date = n.date; - get(i).validTo = n.validTo; + for (Notification storeNotification : store) { + if (storeNotification.id == n.id) { + storeNotification.date = n.date; + storeNotification.validTo = n.validTo; return; } } @@ -72,6 +66,44 @@ public class NotificationStore { Collections.sort(store, new NotificationComparator()); } + public synchronized boolean remove(int id) { + for (int i = 0; i < store.size(); i++) { + if (store.get(i).id == id) { + if (store.get(i).soundId != null) { + Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); + MainApp.instance().stopService(alarm); + } + store.remove(i); + return true; + } + } + return false; + } + + public synchronized void removeExpired() { + for (int i = 0; i < store.size(); i++) { + Notification n = store.get(i); + if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) { + store.remove(i); + i--; + } + } + } + + public void snoozeTo(long timeToSnooze) { + log.debug("Snoozing alarm until: " + timeToSnooze); + SP.putLong("snoozedTo", timeToSnooze); + } + + public void unSnooze() { + if (Notification.isAlarmForStaleData()) { + Notification notification = new Notification(Notification.NSALARM, MainApp.sResources.getString(R.string.nsalarm_staledata), Notification.URGENT); + SP.putLong("snoozedTo", System.currentTimeMillis()); + add(notification); + log.debug("Snoozed to current time and added back notification!"); + } + } + private void raiseSystemNotification(Notification n) { Context context = MainApp.instance().getApplicationContext(); NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); @@ -95,42 +127,4 @@ public class NotificationStore { } mgr.notify(n.id, notificationBuilder.build()); } - - public boolean remove(int id) { - for (int i = 0; i < store.size(); i++) { - if (get(i).id == id) { - if (get(i).soundId != null) { - Intent alarm = new Intent(MainApp.instance().getApplicationContext(), AlarmSoundService.class); - MainApp.instance().stopService(alarm); - } - store.remove(i); - return true; - } - } - return false; - } - - public void removeExpired() { - for (int i = 0; i < store.size(); i++) { - Notification n = get(i); - if (n.validTo.getTime() != 0 && n.validTo.getTime() < System.currentTimeMillis()) { - store.remove(i); - i--; - } - } - } - - public void snoozeTo(long timeToSnooze) { - log.debug("Snoozing alarm until: " + timeToSnooze); - SP.putLong("snoozedTo", timeToSnooze); - } - - public void unSnooze() { - if (Notification.isAlarmForStaleData()) { - Notification notification = new Notification(Notification.NSALARM, MainApp.sResources.getString(R.string.nsalarm_staledata), Notification.URGENT); - SP.putLong("snoozedTo", System.currentTimeMillis()); - add(notification); - log.debug("Snoozed to current time and added back notification!"); - } - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java deleted file mode 100644 index 74b400e1af..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfileFragment.java +++ /dev/null @@ -1,546 +0,0 @@ -package info.nightscout.androidaps.plugins.ProfileCircadianPercentage; - - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.design.widget.Snackbar; -import android.support.v4.app.DialogFragment; -import android.support.v4.content.ContextCompat; -import android.text.Editable; -import android.text.Html; -import android.text.TextWatcher; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.TextView; - -import com.andreabaccega.widget.FormEditText; -import com.squareup.otto.Subscribe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.events.EventInitializationChanged; -import info.nightscout.androidaps.events.EventProfileSwitchChange; -import info.nightscout.androidaps.plugins.Careportal.CareportalFragment; -import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; -import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; -import info.nightscout.androidaps.plugins.Common.SubscriberFragment; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.SafeParse; - -public class CircadianPercentageProfileFragment extends SubscriberFragment { - private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfileFragment.class); - - private static CircadianPercentageProfilePlugin circadianPercentageProfilePlugin = new CircadianPercentageProfilePlugin(); - private Object snackbarCaller; - - public static CircadianPercentageProfilePlugin getPlugin() { - return circadianPercentageProfilePlugin; - } - - FormEditText diaView; - RadioButton mgdlView; - RadioButton mmolView; - FormEditText targetlowView; - FormEditText targethighView; - FormEditText percentageView; - FormEditText timeshiftView; - TextView profileView; - TextView baseprofileIC; - TextView baseprofileBasal; - LinearLayout baseprofileBasalLayout; - TextView baseprofileISF; - Button profileswitchButton; - ImageView percentageIcon; - ImageView timeIcon; - ImageView basaleditIcon; - ImageView iceditIcon; - ImageView isfeditIcon; - BasalEditDialog basalEditDialog; - FrameLayout fl; - Snackbar mSnackBar; - - static Boolean percentageViewHint = true; - static Boolean timeshiftViewHint = true; - - TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - - if (percentageView.testValidity()) { - if (SafeParse.stringToInt(percentageView.getText().toString()) == 0) { - circadianPercentageProfilePlugin.percentage = 100; - } else { - circadianPercentageProfilePlugin.percentage = SafeParse.stringToInt(percentageView.getText().toString()); - } - updateProfileInfo(); - } - if (timeshiftView.testValidity()) { - circadianPercentageProfilePlugin.timeshift = SafeParse.stringToInt(timeshiftView.getText().toString()); - updateProfileInfo(); - } - if (diaView.testValidity()) { - circadianPercentageProfilePlugin.dia = SafeParse.stringToDouble(diaView.getText().toString()); - updateProfileInfo(); - } - if (targethighView.testValidity()) { - circadianPercentageProfilePlugin.targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); - updateProfileInfo(); - } - if (targetlowView.testValidity()) { - circadianPercentageProfilePlugin.targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); - updateProfileInfo(); - } - circadianPercentageProfilePlugin.storeSettings(); - updateProfileInfo(); - } - }; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - - showDeprecatedDialog(); - - View layout = inflater.inflate(R.layout.circadianpercentageprofile_fragment, container, false); - fl = (FrameLayout) layout.findViewById(R.id.circadianpercentageprofile_framelayout); - fl.requestFocusFromTouch(); - diaView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_dia); - mgdlView = (RadioButton) layout.findViewById(R.id.circadianpercentageprofile_mgdl); - mmolView = (RadioButton) layout.findViewById(R.id.circadianpercentageprofile_mmol); - targetlowView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_targetlow); - targethighView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_targethigh); - percentageView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_percentage); - timeshiftView = (FormEditText) layout.findViewById(R.id.circadianpercentageprofile_timeshift); - profileView = (TextView) layout.findViewById(R.id.circadianpercentageprofile_profileview); - baseprofileBasal = (TextView) layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal); - baseprofileBasalLayout = (LinearLayout) layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal_layout); - baseprofileIC = (TextView) layout.findViewById(R.id.circadianpercentageprofile_baseprofileic); - baseprofileISF = (TextView) layout.findViewById(R.id.circadianpercentageprofile_baseprofileisf); - percentageIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_percentageicon); - timeIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_timeicon); - profileswitchButton = (Button) layout.findViewById(R.id.circadianpercentageprofile_profileswitch); - - basaleditIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_basaledit); - iceditIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_icedit); - isfeditIcon = (ImageView) layout.findViewById(R.id.circadianpercentageprofile_isfedit); - - if (!ConfigBuilderPlugin.getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.circadianpercentageprofile_baseprofilebasal_layout).setVisibility(View.GONE); - } - - mgdlView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - circadianPercentageProfilePlugin.mgdl = mgdlView.isChecked(); - circadianPercentageProfilePlugin.mmol = !circadianPercentageProfilePlugin.mgdl; - mmolView.setChecked(circadianPercentageProfilePlugin.mmol); - circadianPercentageProfilePlugin.storeSettings(); - updateProfileInfo(); - } - }); - mmolView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - circadianPercentageProfilePlugin.mmol = mmolView.isChecked(); - circadianPercentageProfilePlugin.mgdl = !circadianPercentageProfilePlugin.mmol; - mgdlView.setChecked(circadianPercentageProfilePlugin.mgdl); - circadianPercentageProfilePlugin.storeSettings(); - updateProfileInfo(); - } - }); - - profileswitchButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - } - }); - - timeIcon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - timeshiftView.requestFocusFromTouch(); - timeshiftView.setSelection(timeshiftView.getText().length()); - ((InputMethodManager) getContext() - .getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(timeshiftView, InputMethodManager.SHOW_IMPLICIT); - } - }); - - percentageIcon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - percentageView.requestFocusFromTouch(); - percentageView.setSelection(percentageView.getText().length()); - ((InputMethodManager) getContext() - .getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(percentageView, InputMethodManager.SHOW_IMPLICIT); - } - }); - - basaleditIcon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - basalEditDialog = new BasalEditDialog(); - basalEditDialog.setup(getPlugin().basebasal, getString(R.string.edit_base_basal), CircadianPercentageProfileFragment.this); - basalEditDialog.show(getFragmentManager(), getString(R.string.edit_base_basal)); - } - }); - - isfeditIcon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - basalEditDialog = new BasalEditDialog(); - basalEditDialog.setup(getPlugin().baseisf, getString(R.string.edit_base_isf), CircadianPercentageProfileFragment.this); - basalEditDialog.show(getFragmentManager(), getString(R.string.edit_base_isf)); - } - }); - - iceditIcon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - basalEditDialog = new BasalEditDialog(); - basalEditDialog.setup(getPlugin().baseic, getString(R.string.edit_base_ic), CircadianPercentageProfileFragment.this); - basalEditDialog.show(getFragmentManager(), getString(R.string.edit_base_ic)); - } - }); - - /*timeshiftView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (!hasFocus) { - if(mSnackBar!=null && snackbarCaller == timeshiftView){ - mSnackBar.dismiss(); - } - timeshiftView.clearFocus(); - fl.requestFocusFromTouch(); - } - else { - if (timeshiftViewHint) { - customSnackbar(view, getString(R.string.timeshift_hint), timeshiftView); - } - } - } - }); - - percentageView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (!hasFocus) { - if(mSnackBar!=null && snackbarCaller == percentageView){ - mSnackBar.dismiss(); - } - percentageView.clearFocus(); - fl.requestFocusFromTouch(); - } - else { - if (percentageViewHint) { - customSnackbar(view, getString(R.string.percentagefactor_hint), percentageView); - } - } - } - });*/ - - diaView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (!hasFocus) { - diaView.clearFocus(); - fl.requestFocusFromTouch(); - } - } - }); - - targethighView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (!hasFocus) { - targethighView.clearFocus(); - fl.requestFocusFromTouch(); - } - } - }); - - targetlowView.setOnFocusChangeListener(new View.OnFocusChangeListener() { - - @Override - public void onFocusChange(View view, boolean hasFocus) { - if (!hasFocus) { - targetlowView.clearFocus(); - fl.requestFocusFromTouch(); - } - } - }); - - - diaView.addTextChangedListener(textWatch); - targetlowView.addTextChangedListener(textWatch); - targethighView.addTextChangedListener(textWatch); - percentageView.addTextChangedListener(textWatch); - timeshiftView.addTextChangedListener(textWatch); - - updateGUI(); - - onStatusEvent(new EventInitializationChanged()); - - return layout; - } - - private void showDeprecatedDialog() { - AlertDialog.Builder adb = new AlertDialog.Builder(getContext()); - adb.setTitle("DEPRECATED! Please migrate!"); - adb.setMessage("CircadianPercentageProfile has been deprecated. " + - "It is recommended to migrate to LocalProfile.\n\n" + - "Good news: You won't lose any functionality! Percentage and Timeshift have been ported to the ProfileSwitch :) \n\n " + - "How to migrate:\n" + - "1) Press MIGRATE, the system will automatically fill the LocalProfile for you.\n" + - "2) Switch to LocalProfile in the ConfigBuilder\n" + - "3) CHECK that all settings are correct in the LocalProfile!!!"); - adb.setIcon(android.R.drawable.ic_dialog_alert); - adb.setPositiveButton("MIGRATE", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - CircadianPercentageProfilePlugin.migrateToLP(); - } - }); - adb.setNegativeButton("Cancel", null); - adb.show(); - } - - public void updateGUI() { - updateProfileInfo(); - - diaView.removeTextChangedListener(textWatch); - targetlowView.removeTextChangedListener(textWatch); - targethighView.removeTextChangedListener(textWatch); - percentageView.removeTextChangedListener(textWatch); - timeshiftView.removeTextChangedListener(textWatch); - - mgdlView.setChecked(circadianPercentageProfilePlugin.mgdl); - mmolView.setChecked(circadianPercentageProfilePlugin.mmol); - diaView.setText(circadianPercentageProfilePlugin.dia.toString()); - targetlowView.setText(circadianPercentageProfilePlugin.targetLow.toString()); - targethighView.setText(circadianPercentageProfilePlugin.targetHigh.toString()); - percentageView.setText("" + circadianPercentageProfilePlugin.percentage); - timeshiftView.setText("" + circadianPercentageProfilePlugin.timeshift); - - - diaView.addTextChangedListener(textWatch); - targetlowView.addTextChangedListener(textWatch); - targethighView.addTextChangedListener(textWatch); - percentageView.addTextChangedListener(textWatch); - timeshiftView.addTextChangedListener(textWatch); - - } - - private void customSnackbar(View view, final String Msg, Object snackbarCaller) { - if (mSnackBar != null) mSnackBar.dismiss(); - - this.snackbarCaller = snackbarCaller; - if (timeshiftViewHint || percentageViewHint) { - //noinspection WrongConstant - mSnackBar = Snackbar.make(view, Msg, 7000) - .setActionTextColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo)) - .setAction(getString(R.string.dont_show_again), new View.OnClickListener() { - @Override - public void onClick(View v) { - if (Msg.equals(getString(R.string.percentagefactor_hint))) { - percentageViewHint = false; - } else if (Msg.equals(getString(R.string.timeshift_hint))) { - timeshiftViewHint = false; - } - } - }); - view = mSnackBar.getView(); - FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); - params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; - view.setLayoutParams(params); - view.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.cardview_dark_background)); - TextView mainTextView = (TextView) (view).findViewById(android.support.design.R.id.snackbar_text); - mainTextView.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.mdtp_white)); - mSnackBar.show(); - } - } - - private void updateProfileInfo() { - StringBuilder sb = new StringBuilder(); - sb.append("

"); - sb.append(getString(R.string.nsprofileview_activeprofile_label)); - sb.append("

"); - sb.append("

"); - sb.append(getString(R.string.nsprofileview_basal_label)); - sb.append(" ( ∑"); - sb.append(DecimalFormatter.to2Decimal(circadianPercentageProfilePlugin.percentageBasalSum())); - sb.append("U )"); - sb.append("

" + circadianPercentageProfilePlugin.basalString()); - sb.append("

"); - sb.append(getString(R.string.nsprofileview_ic_label)); - sb.append("

" + circadianPercentageProfilePlugin.icString()); - sb.append("

"); - sb.append(getString(R.string.nsprofileview_isf_label)); - sb.append("

" + circadianPercentageProfilePlugin.isfString()); - profileView.setText(Html.fromHtml(sb.toString())); - - baseprofileBasal.setText(Html.fromHtml("

" + getString(R.string.base_profile_label) + " ( ∑" + DecimalFormatter.to2Decimal(circadianPercentageProfilePlugin.baseBasalSum()) + "U )

" + - "

" + getString(R.string.nsprofileview_basal_label) + "

" + circadianPercentageProfilePlugin.baseBasalString())); - baseprofileIC.setText(Html.fromHtml("

" + getString(R.string.nsprofileview_ic_label) + "

" + circadianPercentageProfilePlugin.baseIcString())); - baseprofileISF.setText(Html.fromHtml("

" + getString(R.string.nsprofileview_isf_label) + "

" + circadianPercentageProfilePlugin.baseIsfString())); - } - - @Override - public void onStop() { - super.onStop(); - if (basalEditDialog != null && basalEditDialog.isVisible()) { - basalEditDialog.dismiss(); - } - basalEditDialog = null; - fl.requestFocusFromTouch(); - } - - public static class BasalEditDialog extends DialogFragment { - - private double[] values; - private String title; - private CircadianPercentageProfileFragment fragment; - - public void setup(double[] values, String title, CircadianPercentageProfileFragment fragment) { - this.values = values; - this.title = title; - this.fragment = fragment; - } - - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - getDialog().setTitle(title); - View view = inflater.inflate(R.layout.circadianpercentageprofile_editbasal_dialog, container, false); - LinearLayout list = (LinearLayout) view.findViewById(R.id.circadianpp_editbasal_listlayout); - final EditText[] editTexts = new EditText[24]; - for (int i = 0; i < 24; i++) { - View childview = inflater.inflate(R.layout.circadianpercentageprofile_listelement, container, false); - ((TextView) childview.findViewById(R.id.basal_time_elem)).setText((i < 10 ? "0" : "") + i + ":00: "); - - ImageView copyprevbutton = (ImageView) childview.findViewById(R.id.basal_copyprev_elem); - - if (i == 0) { - copyprevbutton.setVisibility(View.INVISIBLE); - } else { - final int j = i; //needs to be final to be passed to inner class. - copyprevbutton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - editTexts[j].setText(editTexts[j - 1].getText()); - } - }); - } - - editTexts[i] = ((EditText) childview.findViewById(R.id.basal_edittext_elem)); - editTexts[i].setText(DecimalFormatter.to2Decimal(values[i])); - list.addView(childview); - } - getDialog().setCancelable(true); - - view.findViewById(R.id.ok_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - for (int i = 0; i < 24; i++) { - if (editTexts[i].getText().length() != 0) { - values[i] = SafeParse.stringToDouble(editTexts[i].getText().toString()); - } - } - fragment.updateProfileInfo(); - getPlugin().storeSettings(); - dismiss(); - } - }); - - view.findViewById(R.id.cancel_action).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - dismiss(); - } - }); - - return view; - } - } - - @Override - public void onPause() { - super.onPause(); - - if (basalEditDialog != null && basalEditDialog.isVisible()) { - basalEditDialog.dismiss(); - } - basalEditDialog = null; - - fl.requestFocusFromTouch(); - } - - @Override - public void onResume() { - super.onResume(); - onStatusEvent(new EventInitializationChanged()); - fl.requestFocusFromTouch(); - } - - @Subscribe - public void onStatusEvent(final EventInitializationChanged e) { - Activity activity = getActivity(); - if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if (!ConfigBuilderPlugin.getActivePump().isInitialized() || ConfigBuilderPlugin.getActivePump().isSuspended()) { - profileswitchButton.setVisibility(View.GONE); - } else { - profileswitchButton.setVisibility(View.VISIBLE); - } - } - }); - } - - @Subscribe - public void onStatusEvent(final EventProfileSwitchChange e) { - Activity activity = getActivity(); - if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - updateGUI(); - } - }); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java deleted file mode 100644 index ec9c6d1e40..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileCircadianPercentage/CircadianPercentageProfilePlugin.java +++ /dev/null @@ -1,455 +0,0 @@ -package info.nightscout.androidaps.plugins.ProfileCircadianPercentage; - -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.text.DecimalFormat; - -import info.nightscout.androidaps.Config; -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; -import info.nightscout.androidaps.plugins.ProfileLocal.LocalProfilePlugin; -import info.nightscout.utils.DecimalFormatter; -import info.nightscout.utils.NSUpload; -import info.nightscout.utils.SP; -import info.nightscout.utils.SafeParse; -import info.nightscout.utils.ToastUtils; - -/** - * Created by Adrian on 12.11.2016. - * Based on SimpleProfile created by mike on 05.08.2016. - */ -public class CircadianPercentageProfilePlugin implements PluginBase, ProfileInterface { - public static final String SETTINGS_PREFIX = "CircadianPercentageProfile"; - private static Logger log = LoggerFactory.getLogger(CircadianPercentageProfilePlugin.class); - - private boolean fragmentEnabled = false; - private boolean fragmentVisible = false; - - private static ProfileStore convertedProfile = null; - private static String convertedProfileName = null; - - boolean mgdl; - boolean mmol; - Double dia; - Double targetLow; - Double targetHigh; - public int percentage; - public int timeshift; - double[] basebasal = new double[]{1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d, 1d}; - double[] baseisf = new double[]{35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d, 35d}; - double[] baseic = new double[]{4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d, 4d}; - - public CircadianPercentageProfilePlugin() { - loadSettings(); - } - - @Override - public String getFragmentClass() { - return CircadianPercentageProfileFragment.class.getName(); - } - - @Override - public int getType() { - return PluginBase.PROFILE; - } - - @Override - public String getName() { - return MainApp.instance().getString(R.string.circadian_percentage_profile); - } - - @Override - public String getNameShort() { - String name = MainApp.sResources.getString(R.string.circadian_percentage_profile_shortname); - if (!name.trim().isEmpty()) { - //only if translation exists - return name; - } - // use long name as fallback - return getName(); - } - - @Override - public boolean isEnabled(int type) { - return type == PROFILE && fragmentEnabled; - } - - @Override - public boolean isVisibleInTabs(int type) { - return type == PROFILE && fragmentVisible; - } - - @Override - public boolean canBeHidden(int type) { - return true; - } - - @Override - public boolean hasFragment() { - return true; - } - - @Override - public boolean showInList(int type) { - return true; - } - - @Override - public void setFragmentEnabled(int type, boolean fragmentEnabled) { - if (type == PROFILE) this.fragmentEnabled = fragmentEnabled; - } - - @Override - public void setFragmentVisible(int type, boolean fragmentVisible) { - if (type == PROFILE) this.fragmentVisible = fragmentVisible; - } - - @Override - public int getPreferencesId() { - return -1; - } - - void storeSettings() { - if (Config.logPrefsChange) - log.debug("Storing settings"); - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean(SETTINGS_PREFIX + "mmol", mmol); - editor.putBoolean(SETTINGS_PREFIX + "mgdl", mgdl); - editor.putString(SETTINGS_PREFIX + "dia", dia.toString()); - editor.putString(SETTINGS_PREFIX + "targetlow", targetLow.toString()); - editor.putString(SETTINGS_PREFIX + "targethigh", targetHigh.toString()); - editor.putString(SETTINGS_PREFIX + "timeshift", timeshift + ""); - editor.putString(SETTINGS_PREFIX + "percentage", percentage + ""); - - - for (int i = 0; i < 24; i++) { - editor.putString(SETTINGS_PREFIX + "basebasal" + i, DecimalFormatter.to2Decimal(basebasal[i])); - editor.putString(SETTINGS_PREFIX + "baseisf" + i, DecimalFormatter.to2Decimal(baseisf[i])); - editor.putString(SETTINGS_PREFIX + "baseic" + i, DecimalFormatter.to2Decimal(baseic[i])); - } - editor.commit(); - createConvertedProfile(); - } - - void loadSettings() { - if (Config.logPrefsChange) - log.debug("Loading stored settings"); - - mgdl = SP.getBoolean(SETTINGS_PREFIX + "mgdl", true); - mmol = SP.getBoolean(SETTINGS_PREFIX + "mmol", false); - dia = SP.getDouble(SETTINGS_PREFIX + "dia", Constants.defaultDIA); - targetLow = SP.getDouble(SETTINGS_PREFIX + "targetlow", 80d); - targetHigh = SP.getDouble(SETTINGS_PREFIX + "targethigh", 120d); - percentage = SP.getInt(SETTINGS_PREFIX + "percentage", 100); - timeshift = SP.getInt(SETTINGS_PREFIX + "timeshift", 0); - - for (int i = 0; i < 24; i++) { - basebasal[i] = SP.getDouble(SETTINGS_PREFIX + "basebasal" + i, basebasal[i]); - baseic[i] = SP.getDouble(SETTINGS_PREFIX + "baseic" + i, baseic[i]); - baseisf[i] = SP.getDouble(SETTINGS_PREFIX + "baseisf" + i, baseisf[i]); - } - } - - public String externallySetParameters(int timeshift, int percentage) { - - String msg = ""; - - if (!fragmentEnabled) { - msg += "NO CPP!" + "\n"; - } - - //check for validity - if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) { - msg += String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage") + "\n"; - } - if (timeshift < 0 || timeshift > 23) { - msg += String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Timeshift") + "\n"; - } - final Profile profile = MainApp.getConfigBuilder().getProfile(); - - if (profile == null || profile.getBasal() == null) { - msg += MainApp.sResources.getString(R.string.cpp_notloadedplugins) + "\n"; - } - if (!"".equals(msg)) { - msg += MainApp.sResources.getString(R.string.cpp_valuesnotstored); - return msg; - } - - //store profile - this.timeshift = timeshift; - this.percentage = percentage; - storeSettings(); - - - //send profile to pumpe - new NewNSTreatmentDialog(); //init - NewNSTreatmentDialog.doProfileSwitch(this.getProfile(), this.getProfileName(), 0, percentage, timeshift); - - //return formatted string - /*msg += "%: " + this.percentage + " h: +" + this.timeshift; - msg += "\n"; - msg += "\nBasal:\n" + basalString() + "\n"; - msg += "\nISF:\n" + isfString() + "\n"; - msg += "\nIC:\n" + isfString() + "\n";*/ - - return msg; - } - - public static void migrateToLP() { - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean("LocalProfile" + "mmol", SP.getBoolean(SETTINGS_PREFIX + "mmol", false)); - editor.putBoolean("LocalProfile" + "mgdl", SP.getBoolean(SETTINGS_PREFIX + "mgdl", true)); - editor.putString("LocalProfile" + "dia", "" + SP.getDouble(SETTINGS_PREFIX + "dia", Constants.defaultDIA)); - editor.putString("LocalProfile" + "ic", getLPic()); - editor.putString("LocalProfile" + "isf", getLPisf()); - editor.putString("LocalProfile" + "basal", getLPbasal()); - try { - JSONArray targetLow = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targetlow", 120d))); - JSONArray targetHigh = new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", SP.getDouble(SETTINGS_PREFIX + "targethigh", 120d))); - editor.putString("LocalProfile" + "targetlow", targetLow.toString()); - editor.putString("LocalProfile" + "targethigh", targetHigh.toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - editor.commit(); - LocalProfilePlugin lp = MainApp.getSpecificPlugin(LocalProfilePlugin.class); - lp.loadSettings(); - - /* TODO: remove Settings and switch to LP later on - * For now only nag the user every time (s)he opens the CPP fragment and offer to migrate. - * Keep settings for now in order to allow the user to check that the migration went well. - */ - //removeSettings(); - - } - - public static String getLPisf() { - return getLPConversion("baseisf", 35d); - } - - public static String getLPic() { - return getLPConversion("baseic", 4); - } - - public static String getLPbasal() { - return getLPConversion("basebasal", 1); - } - - public static String getLPConversion(String type, double defaultValue) { - try { - JSONArray jsonArray = new JSONArray(); - double last = -1d; - - for (int i = 0; i < 24; i++) { - double value = SP.getDouble(SETTINGS_PREFIX + type + i, defaultValue); - String time; - DecimalFormat df = new DecimalFormat("00"); - time = df.format(i) + ":00"; - if (last != value) { - jsonArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", value)); - } - last = value; - } - return jsonArray.toString(); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return LocalProfilePlugin.DEFAULTARRAY; - } - - static void removeSettings() { - if (Config.logPrefsChange) - log.debug("Removing settings"); - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); - SharedPreferences.Editor editor = settings.edit(); - editor.remove(SETTINGS_PREFIX + "mmol"); - editor.remove(SETTINGS_PREFIX + "mgdl"); - editor.remove(SETTINGS_PREFIX + "dia"); - editor.remove(SETTINGS_PREFIX + "targetlow"); - editor.remove(SETTINGS_PREFIX + "targethigh"); - editor.remove(SETTINGS_PREFIX + "timeshift"); - editor.remove(SETTINGS_PREFIX + "percentage"); - - - for (int i = 0; i < 24; i++) { - editor.remove(SETTINGS_PREFIX + "basebasal"); - editor.remove(SETTINGS_PREFIX + "baseisf" + i); - editor.remove(SETTINGS_PREFIX + "baseic" + i); - } - editor.commit(); - } - - private void createConvertedProfile() { - JSONObject json = new JSONObject(); - JSONObject store = new JSONObject(); - JSONObject profile = new JSONObject(); - - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(DecimalFormatter.to2Decimal(sum(basebasal))); - stringBuilder.append("U@"); - stringBuilder.append(percentage); - stringBuilder.append("%>"); - stringBuilder.append(timeshift); - stringBuilder.append("h"); - String profileName = stringBuilder.toString(); - - try { - json.put("defaultProfile", profileName); - json.put("store", store); - profile.put("dia", dia); - - int offset = -(timeshift % 24) + 24; - - JSONArray icArray = new JSONArray(); - JSONArray isfArray = new JSONArray(); - JSONArray basalArray = new JSONArray(); - for (int i = 0; i < 24; i++) { - String time; - DecimalFormat df = new DecimalFormat("00"); - time = df.format(i) + ":00"; - icArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", baseic[(offset + i) % 24] * 100d / percentage)); - isfArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", baseisf[(offset + i) % 24] * 100d / percentage)); - basalArray.put(new JSONObject().put("time", time).put("timeAsSeconds", i * 60 * 60).put("value", basebasal[(offset + i) % 24] * percentage / 100d)); - } - profile.put("carbratio", icArray); - profile.put("sens", isfArray); - profile.put("basal", basalArray); - - - profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetLow))); - profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetHigh))); - profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); - store.put(profileName, profile); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - convertedProfile = new ProfileStore(json); - convertedProfileName = profileName; - } - - @Override - public ProfileStore getProfile() { - if (convertedProfile == null) - createConvertedProfile(); - - performLimitCheck(); - return convertedProfile; - } - - @Override - public String getUnits() { - return mgdl ? Constants.MGDL : Constants.MMOL; - } - - @Override - public String getProfileName() { - if (convertedProfile == null) - createConvertedProfile(); - - performLimitCheck(); - return convertedProfileName; - } - - private void performLimitCheck() { - if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) { - String msg = String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage"); - log.error(msg); - NSUpload.uploadError(msg); - ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); - percentage = Math.max(percentage, Constants.CPP_MIN_PERCENTAGE); - percentage = Math.min(percentage, Constants.CPP_MAX_PERCENTAGE); - } - } - - String basalString() { - return profileString(basebasal, timeshift, percentage, true); - } - - String icString() { - return profileString(baseic, timeshift, percentage, false); - } - - String isfString() { - return profileString(baseisf, timeshift, percentage, false); - } - - String baseIcString() { - return profileString(baseic, 0, 100, false); - } - - String baseIsfString() { - return profileString(baseisf, 0, 100, false); - } - - String baseBasalString() { - return profileString(basebasal, 0, 100, true); - } - - public double baseBasalSum() { - return sum(basebasal); - } - - public double percentageBasalSum() { - double result = 0; - for (int i = 0; i < basebasal.length; i++) { - result += SafeParse.stringToDouble(DecimalFormatter.to2Decimal(basebasal[i] * percentage / 100d)); - } - return result; - } - - - public static double sum(double values[]) { - double result = 0; - for (int i = 0; i < values.length; i++) { - result += values[i]; - } - return result; - } - - - private static String profileString(double[] values, int timeshift, int percentage, boolean inc) { - timeshift = -(timeshift % 24) + 24; - StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append(0); - sb.append("h: "); - sb.append(""); - sb.append(DecimalFormatter.to2Decimal(values[(timeshift + 0) % 24] * (inc ? percentage / 100d : 100d / percentage))); - double prevVal = values[(timeshift + 0) % 24]; - for (int i = 1; i < 24; i++) { - if (prevVal != values[(timeshift + i) % 24]) { - sb.append(", "); - sb.append(""); - sb.append(i); - sb.append("h: "); - sb.append(""); - sb.append(DecimalFormatter.to2Decimal(values[(timeshift + i) % 24] * (inc ? percentage / 100d : 100d / percentage))); - prevVal = values[(timeshift + i) % 24]; - } - } - return sb.toString(); - } - - public int getPercentage() { - return percentage; - } - - public int getTimeshift() { - return timeshift; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java index 364484aff8..fb8e2166e0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileLocal/LocalProfileFragment.java @@ -13,7 +13,6 @@ import android.widget.Button; import android.widget.RadioButton; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -33,6 +32,7 @@ import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SafeParse; import info.nightscout.utils.TimeListEdit; @@ -140,7 +140,7 @@ public class LocalProfileFragment extends SubscriberFragment { return layout; } catch (Exception e) { log.error("Unhandled exception: ", e); - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java index c7d5d8edbf..84a1dd3a87 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java @@ -10,7 +10,6 @@ import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import java.util.ArrayList; @@ -22,6 +21,7 @@ import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; public class NSProfileFragment extends SubscriberFragment implements AdapterView.OnItemSelectedListener { @@ -56,7 +56,7 @@ public class NSProfileFragment extends SubscriberFragment implements AdapterView updateGUI(); return layout; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java index 9a0b64f6d1..b3b2226705 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileSimple/SimpleProfileFragment.java @@ -13,7 +13,6 @@ import android.widget.EditText; import android.widget.RadioButton; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -27,6 +26,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SafeParse; public class SimpleProfileFragment extends SubscriberFragment { @@ -137,7 +137,7 @@ public class SimpleProfileFragment extends SubscriberFragment { return layout; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java index ea47303fb6..fb04b0e105 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/AbstractDanaRPlugin.java @@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.services.AbstractDanaRExecut import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; +import info.nightscout.utils.SP; /** * Created by mike on 28.01.2018. @@ -293,7 +294,7 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, result.isTempCancel = false; result.duration = pump.extendedBolusRemainingMinutes; result.absolute = pump.extendedBolusAbsoluteRate; - result.bolusDelivered = pump.extendedBolusAmount; + if (! SP.getBoolean("danar_useextended", false)) result.bolusDelivered = pump.extendedBolusAmount; result.isPercent = false; if (Config.logPumpActions) log.debug("setExtendedBolus: OK"); @@ -538,11 +539,13 @@ public abstract class AbstractDanaRPlugin implements PluginBase, PumpInterface, if (pump.lastBolusTime.getTime() != 0) { ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } - if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; + TemporaryBasal activeTemp = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (activeTemp != null) { + ret += "Temp: " + activeTemp.toStringFull() + "\n"; } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; + ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (activeExtendedBolus != null) { + ret += "Extended: " + activeExtendedBolus.toString() + "\n"; } if (!veryShort) { ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java index 1ca54a7eb6..06ec42fadc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRFragment.java @@ -15,7 +15,7 @@ import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; + import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -29,6 +29,7 @@ import butterknife.OnClick; import butterknife.Unbinder; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventTempBasalChange; @@ -41,6 +42,7 @@ import info.nightscout.androidaps.plugins.PumpDanaR.events.EventDanaRNewStatus; import info.nightscout.androidaps.queue.events.EventQueueChanged; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.SetWarnColor; public class DanaRFragment extends SubscriberFragment { @@ -100,7 +102,7 @@ public class DanaRFragment extends SubscriberFragment { return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -216,8 +218,9 @@ public class DanaRFragment extends SubscriberFragment { tempBasalView.setText(""); } } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString()); + ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (activeExtendedBolus != null) { + extendedBolusView.setText(activeExtendedBolus.toString()); } else { extendedBolusView.setText(""); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java index 9a0be55897..289e10c518 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/DanaRPlugin.java @@ -134,6 +134,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); + t.isSMB = detailedBolusInfo.isSMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); PumpEnactResult result = new PumpEnactResult(); @@ -315,8 +316,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) return cancelRealTempBasal(); if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() && useExtendedBoluses) { - PumpEnactResult cancelEx = cancelExtendedBolus(); - return cancelEx; + return cancelExtendedBolus(); } PumpEnactResult result = new PumpEnactResult(); result.success = true; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java index 943d4ee502..2e6c02458e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MessageBase.java @@ -23,7 +23,7 @@ import info.nightscout.utils.CRC; public class MessageBase { private static Logger log = LoggerFactory.getLogger(MessageBase.class); - private byte[] buffer = new byte[512]; + protected byte[] buffer = new byte[512]; private int position = 6; public boolean received = false; @@ -34,6 +34,10 @@ public class MessageBase { this.buffer[5] = (byte) (cmd & 0xFF); } + public void resetBuffer() { + position = 6; + } + public void AddParamByte(byte data) { this.buffer[this.position++] = data; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java index 256ccc18da..c97340f44b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusBolusExtended.java @@ -69,8 +69,8 @@ public class MsgStatusBolusExtended extends MessageBase { DanaRPump pump = DanaRPump.getInstance(); long now = System.currentTimeMillis(); - if (treatmentsInterface.isInHistoryExtendedBoluslInProgress()) { - ExtendedBolus extendedBolus = treatmentsInterface.getExtendedBolusFromHistory(System.currentTimeMillis()); + ExtendedBolus extendedBolus = treatmentsInterface.getExtendedBolusFromHistory(System.currentTimeMillis()); + if (extendedBolus != null) { if (pump.isExtendedInProgress) { if (extendedBolus.absoluteRate() != pump.extendedBolusAbsoluteRate) { // Close current extended diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java index d853c9abf1..4727e2650f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/AbstractDanaRExecutionService.java @@ -78,6 +78,8 @@ public abstract class AbstractDanaRExecutionService extends Service { public abstract boolean highTempBasal(int percent); // Rv2 only + public abstract boolean tempBasalShortDuration(int percent, int durationInMinutes); // Rv2 only + public abstract boolean tempBasal(int percent, int durationInHours); public abstract boolean tempBasalStop(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java index 63215464a8..4bf080f3fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/services/DanaRExecutionService.java @@ -354,6 +354,11 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService{ return false; } + @Override + public boolean tempBasalShortDuration(int percent, int durationInMinutes) { + return false; + } + public boolean updateBasalsInPump(final Profile profile) { if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.updatingbasalrates))); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java index 58392e65f9..81e8aad052 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/DanaRKoreanPlugin.java @@ -135,6 +135,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { detailedBolusInfo.insulin = configBuilderPlugin.applyBolusConstraints(detailedBolusInfo.insulin); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); + t.isSMB = detailedBolusInfo.isSMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); PumpEnactResult result = new PumpEnactResult(); @@ -316,8 +317,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) return cancelRealTempBasal(); if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress() && useExtendedBoluses) { - PumpEnactResult cancelEx = cancelExtendedBolus(); - return cancelEx; + return cancelExtendedBolus(); } PumpEnactResult result = new PumpEnactResult(); result.success = true; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java index 6d1ccc132d..12d7590a59 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRKorean/services/DanaRKoreanExecutionService.java @@ -301,6 +301,11 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { return false; } + @Override + public boolean tempBasalShortDuration(int percent, int durationInMinutes) { + return false; + } + public boolean updateBasalsInPump(final Profile profile) { if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.updatingbasalrates))); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java index 9978880e08..20e17af20e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/DanaRSPlugin.java @@ -181,6 +181,8 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, pumpDescription.tempPercentStep = 10; pumpDescription.tempDurationStep = 60; + pumpDescription.tempDurationStep15mAllowed = true; + pumpDescription.tempDurationStep30mAllowed = true; pumpDescription.tempMaxDuration = 24 * 60; @@ -367,7 +369,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, @Override public boolean isInitialized() { - return pump.lastConnection > 0 && pump.maxBasal > 0; + return pump.lastConnection > 0 && pump.maxBasal > 0; } @Override @@ -477,9 +479,10 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, DetailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history Treatment t = new Treatment(); + t.isSMB = detailedBolusInfo.isSMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) - connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 30000, t); // +30s to make the record different + connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000, t); PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; @@ -617,8 +620,13 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, log.debug("setTempBasalPercent: Correct value already set"); return result; } - int durationInHours = Math.max(durationInMinutes / 60, 1); - boolean connectionOK = danaRSService.tempBasal(percent, durationInHours); + boolean connectionOK; + if (durationInMinutes == 15 || durationInMinutes == 30) { + connectionOK = danaRSService.tempBasalShortDuration(percent, durationInMinutes); + } else { + int durationInHours = Math.max(durationInMinutes / 60, 1); + connectionOK = danaRSService.tempBasal(percent, durationInHours); + } if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { result.enacted = true; result.success = true; @@ -820,11 +828,13 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, if (pump.lastBolusTime.getTime() != 0) { ret += "LastBolus: " + DecimalFormatter.to2Decimal(pump.lastBolusAmount) + "U @" + android.text.format.DateFormat.format("HH:mm", pump.lastBolusTime) + "\n"; } - if (MainApp.getConfigBuilder().isInHistoryRealTempBasalInProgress()) { - ret += "Temp: " + MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()).toStringFull() + "\n"; + TemporaryBasal activeTemp = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (activeTemp != null) { + ret += "Temp: " + activeTemp.toStringFull() + "\n"; } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - ret += "Extended: " + MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString() + "\n"; + ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (activeExtendedBolus != null) { + ret += "Extended: " + activeExtendedBolus.toString() + "\n"; } if (!veryShort) { ret += "TDD: " + DecimalFormatter.to0Decimal(pump.dailyTotalUnits) + " / " + pump.maxDailyTotalUnits + " U\n"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java index 06608b5a74..5da3655ceb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_Basal.java @@ -10,33 +10,60 @@ import info.nightscout.androidaps.Config; public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { private static Logger log = LoggerFactory.getLogger(DanaRS_Packet_APS_Basal_Set_Temporary_Basal.class); - private int temporaryBasalRatio; - private int temporaryBasalDuration; + int temporaryBasalRatio; + int temporaryBasalDuration; public int error; - public DanaRS_Packet_APS_Basal_Set_Temporary_Basal() { + final int PARAM30MIN = 160; + final int PARAM15MIN = 150; + + DanaRS_Packet_APS_Basal_Set_Temporary_Basal() { super(); opCode = BleCommandUtil.DANAR_PACKET__OPCODE_BASAL__APS_SET_TEMPORARY_BASAL; } public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent) { this(); + setParams(percent); + } + protected void setParams(int percent) { //HARDCODED LIMITS if (percent < 0) percent = 0; if (percent > 500) percent = 500; temporaryBasalRatio = percent; if (percent < 100) { - temporaryBasalDuration = 160; + temporaryBasalDuration = PARAM30MIN; if (Config.logDanaMessageDetail) log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); } else { - temporaryBasalDuration = 150; + temporaryBasalDuration = PARAM15MIN; if (Config.logDanaMessageDetail) log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); } + } + public DanaRS_Packet_APS_Basal_Set_Temporary_Basal(int percent, boolean fifteenMinutes, boolean thirtyMinutes ) { + this(); + setParams(percent, fifteenMinutes, thirtyMinutes); + } + + protected void setParams(int percent, boolean fifteenMinutes, boolean thirtyMinutes) { + //HARDCODED LIMITS + if (percent < 0) percent = 0; + if (percent > 500) percent = 500; + + temporaryBasalRatio = percent; + if (thirtyMinutes && percent <= 200) { // 30 min is allowed up to 200% + temporaryBasalDuration = PARAM30MIN; + if (Config.logDanaMessageDetail) + log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); + } else { + temporaryBasalDuration = PARAM15MIN; + if (Config.logDanaMessageDetail) + log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); + } } @Override @@ -55,6 +82,7 @@ public class DanaRS_Packet_APS_Basal_Set_Temporary_Basal extends DanaRS_Packet { failed = true; log.error("Set APS temp basal start result: " + result + " FAILED!!!"); } else { + failed = false; if (Config.logDanaMessageDetail) log.debug("Set APS temp basal start result: " + result); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java index 1a1f74b645..489864ebd1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/services/DanaRSService.java @@ -156,7 +156,6 @@ public class DanaRSService extends Service { loadEvents(); - danaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); @@ -190,6 +189,7 @@ public class DanaRSService extends Service { else lastHistoryFetched = 0; log.debug("Events loaded"); + danaRPump.lastConnection = System.currentTimeMillis(); return new PumpEnactResult().success(true); } @@ -318,6 +318,25 @@ public class DanaRSService extends Service { return true; } + public boolean tempBasalShortDuration(Integer percent, int durationInMinutes) { + if (durationInMinutes != 15 && durationInMinutes != 30) { + log.error("Wrong duration param"); + return false; + } + + if (danaRPump.isTempBasalInProgress) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); + bleComm.sendMessage(new DanaRS_Packet_Basal_Set_Cancel_Temporary_Basal()); + SystemClock.sleep(500); + } + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.settingtempbasal))); + bleComm.sendMessage(new DanaRS_Packet_APS_Basal_Set_Temporary_Basal(percent, durationInMinutes == 15, durationInMinutes == 30)); + bleComm.sendMessage(new DanaRS_Packet_Basal_Get_Temporary_Basal_State()); + loadEvents(); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); + return true; + } + public boolean tempBasalStop() { if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java index 34a5b2381b..817df68855 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/DanaRv2Plugin.java @@ -63,6 +63,8 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { pumpDescription.tempPercentStep = 10; pumpDescription.tempDurationStep = 60; + pumpDescription.tempDurationStep15mAllowed = true; + pumpDescription.tempDurationStep30mAllowed = true; pumpDescription.tempMaxDuration = 24 * 60; @@ -148,9 +150,10 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { DetailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history Treatment t = new Treatment(); + t.isSMB = detailedBolusInfo.isSMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) - connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 30000, t); // +30s to make the record different + connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000, t); PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; @@ -274,7 +277,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { } if (percent > getPumpDescription().maxTempPercent) percent = getPumpDescription().maxTempPercent; - TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); + TemporaryBasal runningTB = MainApp.getConfigBuilder().getRealTempBasalFromHistory(System.currentTimeMillis()); if (runningTB != null && runningTB.percentRate == percent && !enforceNew) { result.enacted = false; result.success = true; @@ -288,8 +291,13 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { log.debug("setTempBasalPercent: Correct value already set"); return result; } - int durationInHours = Math.max(durationInMinutes / 60, 1); - boolean connectionOK = sExecutionService.tempBasal(percent, durationInHours); + boolean connectionOK; + if (durationInMinutes == 15 || durationInMinutes == 30) { + connectionOK = sExecutionService.tempBasalShortDuration(percent, durationInMinutes); + } else { + int durationInHours = Math.max(durationInMinutes / 60, 1); + connectionOK = sExecutionService.tempBasal(percent, durationInHours); + } if (connectionOK && pump.isTempBasalInProgress && pump.tempBasalPercent == percent) { result.enacted = true; result.success = true; @@ -335,7 +343,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { @Override public PumpEnactResult cancelTempBasal(boolean force) { PumpEnactResult result = new PumpEnactResult(); - TemporaryBasal runningTB = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); + TemporaryBasal runningTB = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); if (runningTB != null) { sExecutionService.tempBasalStop(); result.enacted = true; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java index da4db61362..6b6e3045de 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgSetAPSTempBasalStart_v2.java @@ -9,28 +9,55 @@ import info.nightscout.androidaps.plugins.PumpDanaR.comm.MessageBase; public class MsgSetAPSTempBasalStart_v2 extends MessageBase { private static Logger log = LoggerFactory.getLogger(MsgSetAPSTempBasalStart_v2.class); + protected final int PARAM30MIN = 160; + protected final int PARAM15MIN = 150; + public MsgSetAPSTempBasalStart_v2() { SetCommand(0xE002); } public MsgSetAPSTempBasalStart_v2(int percent) { this(); + setParams(percent); + } + protected void setParams(int percent) { //HARDCODED LIMITS if (percent < 0) percent = 0; if (percent > 500) percent = 500; AddParamInt(percent); if (percent < 100) { - AddParamByte((byte) 0xA0); // 160 + AddParamByte((byte) PARAM30MIN); if (Config.logDanaMessageDetail) log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); } else { - AddParamByte((byte) 0x96); // 150 + AddParamByte((byte) PARAM15MIN); if (Config.logDanaMessageDetail) log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); } + } + public MsgSetAPSTempBasalStart_v2(int percent, boolean fifteenMinutes, boolean thirtyMinutes) { + this(); + setParams(percent, fifteenMinutes, thirtyMinutes); + } + + protected void setParams(int percent, boolean fifteenMinutes, boolean thirtyMinutes) { + //HARDCODED LIMITS + if (percent < 0) percent = 0; + if (percent > 500) percent = 500; + + AddParamInt(percent); + if (thirtyMinutes && percent <= 200) { // 30 min is allowed up to 200% + AddParamByte((byte) PARAM30MIN); + if (Config.logDanaMessageDetail) + log.debug("APS Temp basal start percent: " + percent + " duration 30 min"); + } else { + AddParamByte((byte) PARAM15MIN); + if (Config.logDanaMessageDetail) + log.debug("APS Temp basal start percent: " + percent + " duration 15 min"); + } } public void handleMessage(byte[] bytes) { @@ -39,6 +66,7 @@ public class MsgSetAPSTempBasalStart_v2 extends MessageBase { failed = true; log.debug("Set APS temp basal start result: " + result + " FAILED!!!"); } else { + failed = false; if (Config.logDanaMessageDetail) log.debug("Set APS temp basal start result: " + result); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java index 81b5837511..1eb73a500a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/services/DanaRv2ExecutionService.java @@ -209,7 +209,6 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { loadEvents(); - mDanaRPump.lastConnection = now; MainApp.bus().post(new EventDanaRNewStatus()); MainApp.bus().post(new EventInitializationChanged()); NSUpload.uploadDeviceStatus(); @@ -255,6 +254,26 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { return true; } + public boolean tempBasalShortDuration(int percent, int durationInMinutes) { + if (durationInMinutes != 15 && durationInMinutes != 30) { + log.error("Wrong duration param"); + return false; + } + + if (!isConnected()) return false; + if (mDanaRPump.isTempBasalInProgress) { + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.stoppingtempbasal))); + mSerialIOThread.sendMessage(new MsgSetTempBasalStop()); + SystemClock.sleep(500); + } + MainApp.bus().post(new EventPumpStatusChanged(MainApp.gs(R.string.settingtempbasal))); + mSerialIOThread.sendMessage(new MsgSetAPSTempBasalStart_v2(percent, durationInMinutes == 15, durationInMinutes == 30)); + mSerialIOThread.sendMessage(new MsgStatusTempBasal_v2()); + loadEvents(); + MainApp.bus().post(new EventPumpStatusChanged(EventPumpStatusChanged.DISCONNECTING)); + return true; + } + public boolean tempBasalStop() { if (!isConnected()) return false; MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal))); @@ -413,6 +432,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { lastHistoryFetched = MsgHistoryEvents_v2.lastEventTimeLoaded - 45 * 60 * 1000L; //always load last 45 min; else lastHistoryFetched = 0; + mDanaRPump.lastConnection = System.currentTimeMillis(); return new PumpEnactResult().success(true); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java index 2d9cb0b202..3dfcb9b0a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpFragment.java @@ -9,7 +9,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import com.crashlytics.android.Crashlytics; + import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.utils.StatusItem; import info.nightscout.androidaps.plugins.PumpInsight.utils.ui.StatusItemViewAdapter; +import info.nightscout.utils.FabricPrivacy; public class InsightPumpFragment extends SubscriberFragment { @@ -64,7 +65,7 @@ public class InsightPumpFragment extends SubscriberFragment { return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java index 3759597ab8..fe5f84d66f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPumpPlugin.java @@ -70,6 +70,7 @@ import static info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers.round * */ +@SuppressWarnings("AccessStaticViaInstance") public class InsightPumpPlugin implements PluginBase, PumpInterface, ConstraintsInterface { private static final long BUSY_WAIT_TIME = 20000; @@ -91,6 +92,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints private PumpDescription pumpDescription = new PumpDescription(); private double basalRate = 0; private Connector connector; + private volatile boolean connector_enabled = false; private final TaskRunner.ResultCallback statusResultHandler = new TaskRunner.ResultCallback() { @Override @@ -119,7 +121,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints }; private InsightPumpPlugin() { - log("InsightPumpPlugin"); + log("InsightPumpPlugin instantiated"); pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.05d; // specification says 0.05U up to 2U then 0.1U @ 2-5U 0.2U @ 10-20U 0.5U 10-20U (are these just UI restrictions?) @@ -136,6 +138,8 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints pumpDescription.tempPercentStep = 10; pumpDescription.tempDurationStep = 15; // 15 minutes up to 24 hours + pumpDescription.tempDurationStep15mAllowed = true; + pumpDescription.tempDurationStep30mAllowed = true; pumpDescription.tempMaxDuration = 24 * 60; pumpDescription.isSetBasalProfileCapable = false; // leave this for now @@ -143,12 +147,8 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints pumpDescription.basalMinimumRate = 0.02d; pumpDescription.isRefillingCapable = true; - //pumpDescription.storesCarbInfo = false; // uncomment when PumpDescription updated to include this + //pumpDescription.storesCarbInfo = false; - this.connector = Connector.get(); - this.connector.init(); - - log("back from init"); } @@ -180,6 +180,31 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints MainApp.bus().post(e); } + private void enableConnector() { + if (!connector_enabled) { + synchronized (this) { + if (!connector_enabled) { + log("Instantiating connector"); + connector_enabled = true; + this.connector = Connector.get(); + this.connector.init(); + } + } + } + } + + private void disableConnector() { + if (connector_enabled) { + synchronized (this) { + if (connector_enabled) { + log("Shutting down connector"); + Connector.get().shutdown(); + connector_enabled = false; + } + } + } + } + @Override public String getFragmentClass() { return InsightPumpFragment.class.getName(); @@ -225,12 +250,19 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints @Override public boolean showInList(int type) { - return true; + return type == PUMP; } @Override public void setFragmentEnabled(int type, boolean fragmentEnabled) { - if (type == PUMP) this.fragmentEnabled = fragmentEnabled; + if (type == PUMP) { + if (fragmentEnabled) { + enableConnector(); + } else { + disableConnector(); + } + this.fragmentEnabled = fragmentEnabled; + } } @Override @@ -285,7 +317,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints if (!connector.isPumpConnected()) { if (Helpers.ratelimit("insight-connect-timer", 40)) { log("Actually requesting a connect"); - connector.getServiceConnector().connect(); + connector.connectToPump(); } } else { log("Already connected"); @@ -306,7 +338,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints try { if (!SP.getBoolean("insight_always_connected", false)) { log("Requesting disconnect"); - connector.getServiceConnector().disconnect(); + connector.disconnectFromPump(); } else { log("Not disconnecting due to preference"); } @@ -322,7 +354,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints if (isConnecting()) { if (!SP.getBoolean("insight_always_connected", false)) { log("Requesting disconnect"); - connector.getServiceConnector().disconnect(); + connector.disconnectFromPump(); } else { log("Not disconnecting due to preference"); } @@ -470,6 +502,8 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints if (percent_amount > 250) percent_amount = 250; + + final SetTBRTaskRunner task = new SetTBRTaskRunner(connector.getServiceConnector(), percent_amount, durationInMinutes); final UUID cmd = aSyncTaskRunner(task, "Set TBR abs: " + absoluteRate + " " + durationInMinutes + "m"); @@ -616,7 +650,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints final UUID cmd; if (fauxTBRcancel) { - cmd = aSyncTaskRunner(new SetTBRTaskRunner(connector.getServiceConnector(), 100, 1), "Faux Cancel TBR - setting " + "90%" + " 1m"); + cmd = aSyncTaskRunner(new SetTBRTaskRunner(connector.getServiceConnector(), 100, 1), "Faux Cancel TBR - setting " + "90%" + " 1m"); } else { cmd = aSyncSingleCommand(new CancelTBRMessage(), "Cancel Temp Basal"); } @@ -893,6 +927,16 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints l.add(new StatusItem(gs(R.string.insight_last_completed_action), LiveHistory.getStatus())); } + final String keep_alive_status = Connector.getKeepAliveString(); + if (keep_alive_status != null) { + l.add(new StatusItem(gs(R.string.insight_keep_alive_status), keep_alive_status)); + } + + final List status_statistics = connector.getStatusStatistics(); + if (status_statistics.size() > 0) { + l.addAll(status_statistics); + } + if (Helpers.ratelimit("insight-status-ui-refresh", 10)) { connector.tryToGetPumpStatusAgain(); } @@ -910,7 +954,7 @@ public class InsightPumpPlugin implements PluginBase, PumpInterface, Constraints public void run() { updateGui(); } - }, 500); + }, 1000); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java index fea7895a27..454795e8d4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/connector/Connector.java @@ -3,12 +3,23 @@ package info.nightscout.androidaps.plugins.PumpInsight.connector; import android.content.Intent; import android.os.PowerManager; +import com.squareup.otto.Subscribe; + +import java.util.ArrayList; +import java.util.Formatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.plugins.PumpInsight.events.EventInsightPumpUpdateGui; import info.nightscout.androidaps.plugins.PumpInsight.history.HistoryReceiver; import info.nightscout.androidaps.plugins.PumpInsight.history.LiveHistory; import info.nightscout.androidaps.plugins.PumpInsight.utils.Helpers; +import info.nightscout.androidaps.plugins.PumpInsight.utils.StatusItem; +import info.nightscout.utils.SP; import sugar.free.sightparser.handling.ServiceConnectionCallback; import sugar.free.sightparser.handling.SightServiceConnector; import sugar.free.sightparser.handling.StatusCallback; @@ -31,11 +42,17 @@ import static sugar.free.sightparser.handling.SightService.COMPATIBILITY_VERSION public class Connector { + // TODO connection statistics + private static final String TAG = "InsightConnector"; private static final String COMPANION_APP_PACKAGE = "sugar.free.sightremote"; private final static long FRESH_MS = 70000; + private static final Map statistics = new HashMap<>(); private static volatile Connector instance; private static volatile HistoryReceiver historyReceiver; + private static volatile long stayConnectedTill = -1; + private static volatile long stayConnectedTime = 0; + private static volatile boolean disconnect_thread_running = false; private volatile SightServiceConnector serviceConnector; private volatile Status lastStatus = null; private String compatabilityMessage = null; @@ -47,14 +64,22 @@ public class Connector { @Override public synchronized void onStatusChange(Status status) { - log("Status change: " + status); - lastStatus = status; - lastStatusTime = Helpers.tsl(); - if (status == Status.CONNECTED) { - lastContactTime = lastStatusTime; - } + if ((status != lastStatus) || (Helpers.msSince(lastStatusTime) > 2000)) { + log("Status change: " + status); - MainApp.bus().post(new EventInsightPumpUpdateGui()); + updateStatusStatistics(lastStatus, lastStatusTime); + lastStatus = status; + lastStatusTime = Helpers.tsl(); + + if (status == Status.CONNECTED) { + lastContactTime = lastStatusTime; + extendKeepAliveIfActive(); + } + + MainApp.bus().post(new EventInsightPumpUpdateGui()); + } else { + log("Same status as before: " + status); + } } }; @@ -97,6 +122,7 @@ public class Connector { private Connector() { initializeHistoryReceiver(); + MainApp.bus().register(this); } public static Connector get() { @@ -117,10 +143,30 @@ public class Connector { } public static void connectToPump() { - log("Attempting to connect to pump"); + connectToPump(0); + } + + public synchronized static void connectToPump(long keep_alive) { + log("Attempting to connect to pump."); + if (keep_alive > 0) { + stayConnectedTime = keep_alive; + stayConnectedTill = Helpers.tsl() + keep_alive; + log("Staying connected till: " + Helpers.dateTimeText(stayConnectedTill)); + delayedDisconnectionThread(); + } get().getServiceConnector().connect(); } + public static void disconnectFromPump() { + if (Helpers.tsl() >= stayConnectedTill) { + log("Requesting real pump disconnect"); + get().getServiceConnector().disconnect(); + } else { + log("Cannot disconnect as due to keep alive till: " + Helpers.dateTimeText(stayConnectedTill)); + // TODO set a disconnection timer? + } + } + static void log(String msg) { android.util.Log.e("INSIGHTPUMP", msg); } @@ -160,6 +206,104 @@ public class Connector { return MainApp.instance().getString(id); } + private static synchronized void extendKeepAliveIfActive() { + if (keepAliveActive()) { + if (Helpers.ratelimit("extend-insight-keepalive", 10)) { + stayConnectedTill = Helpers.tsl() + stayConnectedTime; + log("Keep-alive extended until: " + Helpers.dateTimeText(stayConnectedTill)); + } + } + } + + private static boolean keepAliveActive() { + return Helpers.tsl() <= stayConnectedTill; + } + + public static String getKeepAliveString() { + if (keepAliveActive()) { + return MainApp.instance().getString(R.string.insight_keepalive_format_string, + stayConnectedTime / 1000, Helpers.hourMinuteSecondString(stayConnectedTill)); + + } else { + return null; + } + } + + private static synchronized void delayedDisconnectionThread() { + if (keepAliveActive()) { + if (!disconnect_thread_running) { + disconnect_thread_running = true; + new Thread(new Runnable() { + @Override + public void run() { + final PowerManager.WakeLock wl = Helpers.getWakeLock("insight-disconnection-timer", 600000); + try { + while (disconnect_thread_running && keepAliveActive()) { + if (Helpers.ratelimit("insight-expiry-notice", 5)) { + log("Staying connected thread expires: " + Helpers.dateTimeText(stayConnectedTill)); + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // + } + } + + if (disconnect_thread_running) { + log("Sending the real delayed disconnect"); + get().getServiceConnector().disconnect(); + } else { + log("Disconnect thread already terminating"); + } + } finally { + Helpers.releaseWakeLock(wl); + disconnect_thread_running = false; + } + } + }).start(); + } else { + log("Disconnect thread already running"); + } + } + } + + private static long percentage(long t, long total) { + return (long) (Helpers.roundDouble(((double) t * 100) / total, 0)); + } + + public synchronized void shutdown() { + if (instance != null) { + log("Attempting to shut down connector"); + try { + disconnect_thread_running = false; + try { + instance.serviceConnector.setConnectionCallback(null); + } catch (Exception e) { + // + } + try { + instance.serviceConnector.removeStatusCallback(statusCallback); + } catch (Exception e) { + // + } + try { + instance.serviceConnector.disconnect(); + } catch (Exception e) { + log("Exception disconnecting: " + e); + } + try { + instance.serviceConnector.disconnectFromService(); + } catch (Exception e) { + log("Excpetion disconnecting service: " + e); + } + instance.serviceConnector = null; + instance = null; + } catch (Exception e) { + log("Exception shutting down: " + e); + } + } + } + @SuppressWarnings("AccessStaticViaInstance") private synchronized void initializeHistoryReceiver() { if (historyReceiver == null) { @@ -354,4 +498,57 @@ public class Connector { return true; // TODO evaluate whether current } + private void updateStatusStatistics(Status last, long since) { + if ((last != null) && (since > 0)) { + Long total = statistics.get(last); + if (total == null) total = 0L; + statistics.put(last, total + Helpers.msSince(since)); + log("Updated statistics for: " + last + " total: " + Helpers.niceTimeScalar(statistics.get(last))); + // TODO persist data + } + } + + public List getStatusStatistics() { + final List l = new ArrayList<>(); + long total = 0; + for (Map.Entry entry : statistics.entrySet()) { + total += getEntryTime(entry); + } + for (Map.Entry entry : statistics.entrySet()) { + if ((long) entry.getValue() > 1000) { + l.add(new StatusItem(gs(R.string.statistics) + " " + Helpers.capitalize(entry.getKey().toString()), + new Formatter().format("%4s %12s", + percentage(getEntryTime(entry), total) + "%", + Helpers.niceTimeScalar(getEntryTime(entry))).toString())); + } + } + return l; + } + + private long getEntryTime(Map.Entry entry) { + return (long) entry.getValue() + (entry.getKey().equals(lastStatus) ? Helpers.msSince(lastStatusTime) : 0); + } + + @Subscribe + public void onStatusEvent(final EventFeatureRunning ev) { + new Thread(new Runnable() { + @Override + public void run() { + if (isConnected()) { + if (SP.getBoolean("insight_preemptive_connect", true)) { + switch (ev.getFeature()) { + case WIZARD: + log("Wizard feature detected, preconnecting to pump"); + connectToPump(120 * 1000); + break; + case MAIN: + log("Main feature detected, preconnecting to pump"); + connectToPump(30 * 1000); + break; + } + } + } + } + }).start(); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java index 5375d88b7b..b4618ae3b5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryIntentAdapter.java @@ -36,7 +36,10 @@ class HistoryIntentAdapter { final int pump_tbr_duration = intent.getIntExtra(HistoryBroadcast.EXTRA_DURATION, -1); final int pump_tbr_percent = intent.getIntExtra(HistoryBroadcast.EXTRA_TBR_AMOUNT, -1); - final int pump_record_id = intent.getIntExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); + long pump_record_id = intent.getLongExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); + if (pump_record_id == -1) { + pump_record_id = intent.getIntExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); + } final long pump_serial_number = Long.parseLong(intent.getStringExtra(HistoryBroadcast.EXTRA_PUMP_SERIAL_NUMBER)); final Date event_time = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); final Date start_time = getDateExtra(intent, HistoryBroadcast.EXTRA_START_TIME); @@ -60,8 +63,11 @@ class HistoryIntentAdapter { void processDeliveredBolusIntent(Intent intent) { final String bolus_type = intent.getStringExtra(HistoryBroadcast.EXTRA_BOLUS_TYPE); - final int bolus_id = intent.getIntExtra(HistoryBroadcast.EXTRA_BOLUS_ID,-1); - final int pump_record_id = intent.getIntExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); + final int bolus_id = intent.getIntExtra(HistoryBroadcast.EXTRA_BOLUS_ID, -1); + long pump_record_id = intent.getLongExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); + if (pump_record_id == -1) { + pump_record_id = intent.getIntExtra(HistoryBroadcast.EXTRA_EVENT_NUMBER, -1); + } final long pump_serial_number = Long.parseLong(intent.getStringExtra(HistoryBroadcast.EXTRA_PUMP_SERIAL_NUMBER)); final Date event_time = getDateExtra(intent, HistoryBroadcast.EXTRA_EVENT_TIME); final Date start_time = getDateExtra(intent, HistoryBroadcast.EXTRA_START_TIME); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java index ce4f7522a7..588074b0c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java @@ -17,7 +17,7 @@ import info.nightscout.androidaps.db.TemporaryBasal; class HistoryLogAdapter { - private static final long MAX_TIME_DIFFERENCE = 5000; + private static final long MAX_TIME_DIFFERENCE = 61000; private static void log(String msg) { android.util.Log.e("HISTORYLOG", msg); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java index ce86f33e16..a2abda40d7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/utils/Helpers.java @@ -162,6 +162,31 @@ public class Helpers { return niceTimeScalar(t).replaceFirst("^1 ", ""); } + public static String niceTimeScalarBrief(long t) { + // TODO i18n wont work for non-latin characterset + return niceTimeScalar(t).replaceFirst("([a-z])[a-z]*", "$1").replace(" ",""); + } + + public static String hourMinuteString(long timestamp) { + return android.text.format.DateFormat.format("kk:mm", timestamp).toString(); + } + + public static String hourMinuteSecondString(long timestamp) { + return android.text.format.DateFormat.format("kk:mm:ss", timestamp).toString(); + } + + public static String dateTimeText(long timestamp) { + return android.text.format.DateFormat.format("yyyy-MM-dd kk:mm:ss", timestamp).toString(); + } + + public static String dateText(long timestamp) { + return android.text.format.DateFormat.format("yyyy-MM-dd", timestamp).toString(); + } + + public static String capitalize(String text) { + return text.substring(0, 1).toUpperCase() + text.substring(1).toLowerCase(); + } + public static double roundDouble(double value, int places) { if (places < 0) throw new IllegalArgumentException("Invalid decimal places"); BigDecimal bd = new BigDecimal(value); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java index ebaf2b19dd..f367e8917e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpFragment.java @@ -10,7 +10,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; + import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -18,8 +18,11 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.db.ExtendedBolus; +import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.PumpVirtual.events.EventVirtualPumpUpdateGui; +import info.nightscout.utils.FabricPrivacy; public class VirtualPumpFragment extends SubscriberFragment { private static Logger log = LoggerFactory.getLogger(VirtualPumpFragment.class); @@ -61,7 +64,7 @@ public class VirtualPumpFragment extends SubscriberFragment { return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; @@ -81,13 +84,15 @@ public class VirtualPumpFragment extends SubscriberFragment { public void run() { VirtualPumpPlugin virtualPump = VirtualPumpPlugin.getPlugin(); basaBasalRateView.setText(virtualPump.getBaseBasalRate() + "U"); - if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - tempBasalView.setText(MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()).toStringFull()); + TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); + if (activeTemp != null) { + tempBasalView.setText(activeTemp.toStringFull()); } else { tempBasalView.setText(""); } - if (MainApp.getConfigBuilder().isInHistoryExtendedBoluslInProgress()) { - extendedBolusView.setText(MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()).toString()); + ExtendedBolus activeExtendedBolus = MainApp.getConfigBuilder().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (activeExtendedBolus != null) { + extendedBolusView.setText(activeExtendedBolus.toString()); } else { extendedBolusView.setText(""); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index 1c9fdaaaf7..346750fa0a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -89,6 +89,8 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { pumpDescription.tempPercentStep = 10; pumpDescription.tempDurationStep = 30; + pumpDescription.tempDurationStep15mAllowed = true; + pumpDescription.tempDurationStep30mAllowed = true; pumpDescription.tempMaxDuration = 24 * 60; @@ -97,6 +99,8 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { pumpDescription.basalMinimumRate = 0.01d; pumpDescription.isRefillingCapable = false; + + pumpDescription.storesCarbInfo = false; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java index f45d6cec40..ebe8ddfe31 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityAAPS/SensitivityAAPSPlugin.java @@ -105,7 +105,7 @@ public class SensitivityAAPSPlugin implements PluginBase, SensitivityInterface{ @Override public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable(); + LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -119,7 +119,7 @@ public class SensitivityAAPSPlugin implements PluginBase, SensitivityInterface{ return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already + AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already if (current == null) { log.debug("No autosens data available"); return new AutosensResult(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java index bf7d6ce8f5..eaabb4ecc9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityOref0/SensitivityOref0Plugin.java @@ -104,7 +104,7 @@ public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface @Override public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable(); + LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -120,7 +120,7 @@ public class SensitivityOref0Plugin implements PluginBase, SensitivityInterface return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already + AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already if (current == null) { log.debug("No current autosens data available"); return new AutosensResult(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java index 5f9e996a8a..91053e2654 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SensitivityWeightedAverage/SensitivityWeightedAveragePlugin.java @@ -101,7 +101,7 @@ public class SensitivityWeightedAveragePlugin implements PluginBase, Sensitivity @Override public AutosensResult detectSensitivity(long fromTime, long toTime) { - LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getAutosensDataTable(); + LongSparseArray autosensDataTable = IobCobCalculatorPlugin.getPlugin().getAutosensDataTable(); String age = SP.getString(R.string.key_age, ""); int defaultHours = 24; @@ -116,7 +116,7 @@ public class SensitivityWeightedAveragePlugin implements PluginBase, Sensitivity return new AutosensResult(); } - AutosensData current = IobCobCalculatorPlugin.getAutosensData(toTime); // this is running inside lock already + AutosensData current = IobCobCalculatorPlugin.getPlugin().getAutosensData(toTime); // this is running inside lock already if (current == null) { if (Config.logAutosensData) log.debug("No autosens data available"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java index b64049c098..d10786f8e5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SmsCommunicator/SmsCommunicatorFragment.java @@ -10,7 +10,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -23,6 +22,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; /** * A simple {@link Fragment} subclass. @@ -47,7 +47,7 @@ public class SmsCommunicatorFragment extends SubscriberFragment { updateGUI(); return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; 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 b7b9d879b1..01f883e6d6 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 @@ -5,7 +5,6 @@ import android.content.pm.ResolveInfo; import android.telephony.SmsManager; import android.telephony.SmsMessage; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -41,6 +40,7 @@ import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventNewSMS; import info.nightscout.androidaps.plugins.SmsCommunicator.events.EventSmsCommunicatorUpdateGui; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -276,7 +276,7 @@ public class SmsCommunicatorPlugin implements PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Bg")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Bg")); break; case "LOOP": if (splited.length > 1) @@ -297,7 +297,7 @@ public class SmsCommunicatorPlugin implements PluginBase { }); } receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Stop")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Stop")); break; case "ENABLE": case "START": @@ -309,7 +309,7 @@ public class SmsCommunicatorPlugin implements PluginBase { MainApp.bus().post(new EventRefreshOverview("SMS_LOOP_START")); } receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Start")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Start")); break; case "STATUS": loopPlugin = MainApp.getSpecificPlugin(LoopPlugin.class); @@ -325,7 +325,7 @@ public class SmsCommunicatorPlugin implements PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); } receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Status")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Status")); break; case "RESUME": final LoopPlugin activeloop = ConfigBuilderPlugin.getActiveLoop(); @@ -334,7 +334,7 @@ public class SmsCommunicatorPlugin implements PluginBase { NSUpload.uploadOpenAPSOffline(0); reply = MainApp.sResources.getString(R.string.smscommunicator_loopresumed); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply, new Date())); - Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Resume")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Resume")); break; case "SUSPEND": if (splited.length >= 3) @@ -351,7 +351,7 @@ public class SmsCommunicatorPlugin implements PluginBase { resetWaitingMessages(); sendSMS(suspendWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); suspendWaitingForConfirmation.duration = duration; - Answers.getInstance().logCustom(new CustomEvent("SMS_Loop_Suspend")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Loop_Suspend")); } else { reply = MainApp.sResources.getString(R.string.smscommunicator_remotecommandnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -370,7 +370,7 @@ public class SmsCommunicatorPlugin implements PluginBase { reply = "TERATMENTS REFRESH " + q.size() + " receivers"; sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Treatments_Refresh")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Treatments_Refresh")); break; } break; @@ -384,7 +384,7 @@ public class SmsCommunicatorPlugin implements PluginBase { reply = "NSCLIENT RESTART " + q.size() + " receivers"; sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Nsclient_Restart")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Nsclient_Restart")); break; } break; @@ -400,7 +400,7 @@ public class SmsCommunicatorPlugin implements PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); } receivedSms.processed = true; - Answers.getInstance().logCustom(new CustomEvent("SMS_Danar")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Danar")); break; case "BASAL": if (splited.length > 1) { @@ -411,7 +411,7 @@ public class SmsCommunicatorPlugin implements PluginBase { receivedSms.processed = true; resetWaitingMessages(); sendSMS(cancelTempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); - Answers.getInstance().logCustom(new CustomEvent("SMS_Basal")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); } else { reply = MainApp.sResources.getString(R.string.smscommunicator_remotebasalnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -426,7 +426,7 @@ public class SmsCommunicatorPlugin implements PluginBase { resetWaitingMessages(); sendSMS(tempBasalWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); tempBasalWaitingForConfirmation.tempBasal = tempBasal; - Answers.getInstance().logCustom(new CustomEvent("SMS_Basal")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Basal")); } else { reply = MainApp.sResources.getString(R.string.smscommunicator_remotebasalnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -451,7 +451,7 @@ public class SmsCommunicatorPlugin implements PluginBase { resetWaitingMessages(); sendSMS(bolusWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); bolusWaitingForConfirmation.bolusRequested = amount; - Answers.getInstance().logCustom(new CustomEvent("SMS_Bolus")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Bolus")); } else { reply = MainApp.sResources.getString(R.string.smscommunicator_remotebolusnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); @@ -468,7 +468,7 @@ public class SmsCommunicatorPlugin implements PluginBase { resetWaitingMessages(); sendSMS(calibrationWaitingForConfirmation = new Sms(receivedSms.phoneNumber, reply, new Date(), passCode)); calibrationWaitingForConfirmation.calibrationRequested = amount; - Answers.getInstance().logCustom(new CustomEvent("SMS_Cal")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("SMS_Cal")); } else { reply = MainApp.sResources.getString(R.string.smscommunicator_remotecalibrationnotallowed); sendSMS(new Sms(receivedSms.phoneNumber, reply, new Date())); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java index 0b001b8b80..4b3208a2bf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/BGSourceFragment.java @@ -12,7 +12,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -29,6 +28,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; /** @@ -63,7 +63,7 @@ public class BGSourceFragment extends SubscriberFragment { return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java index 193801ac28..8b9734cb79 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/SourceDexcomG5/SourceDexcomG5Plugin.java @@ -39,8 +39,7 @@ public class SourceDexcomG5Plugin implements PluginBase, BgSourceInterface { @Override public String getNameShort() { - // use long name as fallback (no tabs) - return getName(); + return MainApp.gs(R.string.dexcomG5_shortname); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java index b10ad96697..dc01656992 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsFragment.java @@ -8,7 +8,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; + import com.squareup.otto.Subscribe; import org.slf4j.Logger; @@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsExtende import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsProfileSwitchFragment; import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsTempTargetFragment; import info.nightscout.androidaps.plugins.Treatments.fragments.TreatmentsTemporaryBasalsFragment; +import info.nightscout.utils.FabricPrivacy; public class TreatmentsFragment extends SubscriberFragment implements View.OnClickListener { private static Logger log = LoggerFactory.getLogger(TreatmentsFragment.class); @@ -60,7 +61,7 @@ public class TreatmentsFragment extends SubscriberFragment implements View.OnCli return view; } catch (Exception e) { - Crashlytics.logException(e); + FabricPrivacy.logException(e); } return null; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java index dad53a0560..1842d3b504 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java @@ -252,7 +252,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } } - AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensDataSynchronized("getMealData()"); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("getMealData()"); if (autosensData != null) { result.mealCOB = autosensData.cob; result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java index 99c89f0706..baf1e43d55 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java @@ -17,7 +17,6 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -38,6 +37,7 @@ import info.nightscout.androidaps.events.EventTreatmentChange; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; @@ -155,7 +155,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. MainApp.getDbHelper().delete(treatment); } updateGUI(); - Answers.getInstance().logCustom(new CustomEvent("RemoveTreatment")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("RemoveTreatment")); } }); builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java index 4e21259dae..1cb6d04614 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java @@ -16,7 +16,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -34,6 +33,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.androidaps.data.Intervals; @@ -155,7 +155,7 @@ public class TreatmentsExtendedBolusesFragment extends SubscriberFragment { UploadQueue.removeID("dbAdd", _id); } MainApp.getDbHelper().delete(extendedBolus); - Answers.getInstance().logCustom(new CustomEvent("RemoveExtendedBolus")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("RemoveExtendedBolus")); } }); builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java index bd6269e871..c883bc8757 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java @@ -16,7 +16,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.squareup.otto.Subscribe; @@ -34,6 +33,7 @@ import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.NSClientInternal.UploadQueue; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.androidaps.data.Intervals; @@ -172,7 +172,7 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment { UploadQueue.removeID("dbAdd", _id); } MainApp.getDbHelper().delete(tempBasal); - Answers.getInstance().logCustom(new CustomEvent("RemoveTempBasal")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("RemoveTempBasal")); } }); builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java index fbec0a2308..636a935787 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.Wear; +import android.Manifest; import android.os.HandlerThread; import android.support.annotation.NonNull; @@ -44,6 +45,7 @@ import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.HardLimits; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; import info.nightscout.utils.ToastUtils; @@ -149,11 +151,11 @@ public class ActionStringHandler { low *= Constants.MMOLL_TO_MGDL; high *= Constants.MMOLL_TO_MGDL; } - if (low < Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[0] || low > Constants.VERY_HARD_LIMIT_TEMP_MIN_BG[1]) { + if (low < HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0] || low > HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]) { sendError("Min-BG out of range!"); return; } - if (high < Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[0] || high > Constants.VERY_HARD_LIMIT_TEMP_MAX_BG[1]) { + if (high < HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0] || high > HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]) { sendError("Max-BG out of range!"); return; } @@ -577,18 +579,18 @@ public class ActionStringHandler { //check for validity if (percentage < Constants.CPP_MIN_PERCENTAGE || percentage > Constants.CPP_MAX_PERCENTAGE) { - msg += String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Percentage") + "\n"; + msg += String.format(MainApp.sResources.getString(R.string.valueoutofrange), "Profile-Percentage") + "\n"; } if (timeshift < 0 || timeshift > 23) { - msg += String.format(MainApp.sResources.getString(R.string.openapsma_valueoutofrange), "Profile-Timeshift") + "\n"; + msg += String.format(MainApp.sResources.getString(R.string.valueoutofrange), "Profile-Timeshift") + "\n"; } final Profile profile = MainApp.getConfigBuilder().getProfile(); if (profile == null || profile.getBasal() == null) { - msg += MainApp.sResources.getString(R.string.cpp_notloadedplugins) + "\n"; + msg += MainApp.sResources.getString(R.string.notloadedplugins) + "\n"; } if (!"".equals(msg)) { - msg += MainApp.sResources.getString(R.string.cpp_valuesnotstored); + msg += MainApp.sResources.getString(R.string.valuesnotstored); String rTitle = "STATUS"; String rAction = "statusmessage"; WearPlugin.getPlugin().requestActionConfirmation(rTitle, msg, rAction); @@ -643,16 +645,20 @@ public class ActionStringHandler { detailedBolusInfo.insulin = amount; detailedBolusInfo.carbs = carbs; detailedBolusInfo.source = Source.USER; - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { - @Override - public void run() { - if (!result.success) { - sendError(MainApp.sResources.getString(R.string.treatmentdeliveryerror) + - "\n" + - result.comment); + if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { + ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + if (!result.success) { + sendError(MainApp.sResources.getString(R.string.treatmentdeliveryerror) + + "\n" + + result.comment); + } } - } - }); + }); + } else { + MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + } } private synchronized static void sendError(String errormessage) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java index 3316d68d12..b72a767278 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/WearPlugin.java @@ -197,10 +197,12 @@ public class WearPlugin implements PluginBase { @Subscribe public void onStatusEvent(final EventOverviewBolusProgress ev) { - Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS); - intent.putExtra("progresspercent", ev.percent); - intent.putExtra("progressstatus", ev.status); - ctx.startService(intent); + if(!ev.isSMB()||SP.getBoolean("wear_notifySMB", false)) { + Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS); + intent.putExtra("progresspercent", ev.percent); + intent.putExtra("progressstatus", ev.status); + ctx.startService(intent); + } } @Subscribe 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 4adec23560..74423fe7ac 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 @@ -663,7 +663,7 @@ public class WatchUpdaterService extends WearableListenerService implements private String generateCOBString() { String cobStringResult = "--"; - AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensData("WatcherUpdaterService"); + AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("WatcherUpdaterService"); if (autosensData != null) { cobStringResult = (int) autosensData.cob + "g"; } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java index c5fb9821bc..f241ab74cf 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/QueueThread.java @@ -41,7 +41,7 @@ public class QueueThread extends Thread { this.queue = queue; PowerManager powerManager = (PowerManager) MainApp.instance().getApplicationContext().getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "QueueThread"); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "QueueThread"); } @Override diff --git a/app/src/main/java/info/nightscout/utils/FabricPrivacy.java b/app/src/main/java/info/nightscout/utils/FabricPrivacy.java new file mode 100644 index 0000000000..bd117ed5c3 --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/FabricPrivacy.java @@ -0,0 +1,83 @@ +package info.nightscout.utils; + +import com.crashlytics.android.Crashlytics; +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.CustomEvent; + +/** + * Created by jamorham on 21/02/2018. + * + * Some users do not wish to be tracked, Fabric Answers and Crashlytics do not provide an easy way + * to disable them and make calls from a potentially invalid singleton reference. This wrapper + * emulates the methods but ignores the request if the instance is null or invalid. + * + */ + +public class FabricPrivacy { + + private static final String TAG = "FabricPrivacy"; + private static volatile FabricPrivacy instance; + + + public static FabricPrivacy getInstance() { + if (instance == null) { + initSelf(); + } + return instance; + } + + private static synchronized void initSelf() { + if (instance == null) { + instance = new FabricPrivacy(); + } + } + + // Crashlytics logException + public static void logException(Throwable throwable) { + try { + final Crashlytics crashlytics = Crashlytics.getInstance(); + crashlytics.core.logException(throwable); + } catch (NullPointerException | IllegalStateException e) { + android.util.Log.d(TAG, "Ignoring opted out non-initialized log: " + throwable); + } + } + + // Crashlytics log + public static void log(String msg) { + try { + final Crashlytics crashlytics = Crashlytics.getInstance(); + crashlytics.core.log(msg); + } catch (NullPointerException | IllegalStateException e) { + android.util.Log.d(TAG, "Ignoring opted out non-initialized log: " + msg); + } + } + + // Crashlytics log + public static void log(int priority, String tag, String msg) { + try { + final Crashlytics crashlytics = Crashlytics.getInstance(); + crashlytics.core.log(priority, tag, msg); + } catch (NullPointerException | IllegalStateException e) { + android.util.Log.d(TAG, "Ignoring opted out non-initialized log: " + msg); + } + } + + public static boolean fabricEnabled() { + return SP.getBoolean("enable_fabric", true); + } + + // Answers logCustom + public void logCustom(CustomEvent event) { + try { + final Answers answers = Answers.getInstance(); + if (fabricEnabled()) { + answers.logCustom(event); + } else { + android.util.Log.d(TAG, "Ignoring recently opted-out event: " + event.toString()); + } + } catch (NullPointerException | IllegalStateException e) { + android.util.Log.d(TAG, "Ignoring opted-out non-initialized event: " + event.toString()); + } + } + +} diff --git a/app/src/main/java/info/nightscout/utils/HardLimits.java b/app/src/main/java/info/nightscout/utils/HardLimits.java index ff92cf2e87..1b39951b85 100644 --- a/app/src/main/java/info/nightscout/utils/HardLimits.java +++ b/app/src/main/java/info/nightscout/utils/HardLimits.java @@ -1,5 +1,8 @@ package info.nightscout.utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -8,17 +11,90 @@ import info.nightscout.androidaps.R; */ public class HardLimits { - final static double MAXBOLUS_ADULT = 17d; - final static double MAXBOLUS_TEENAGE = 10d; - final static double MAXBOLUS_CHILD = 5d; + private static Logger log = LoggerFactory.getLogger(HardLimits.class); - public static double maxBolus() { - String age = SP.getString(R.string.key_age, ""); + final static int CHILD = 0; + final static int TEENAGE = 1; + final static int ADULT = 2; + final static int RESISTANTADULT = 3; - if (age.equals(MainApp.sResources.getString(R.string.key_adult))) return MAXBOLUS_ADULT; - if (age.equals(MainApp.sResources.getString(R.string.key_teenage))) return MAXBOLUS_TEENAGE; - if (age.equals(MainApp.sResources.getString(R.string.key_child))) return MAXBOLUS_CHILD; - return MAXBOLUS_ADULT; + final static double[] MAXBOLUS = {5d, 10d, 17d, 21d}; + + // Very Hard Limits Ranges + // First value is the Lowest and second value is the Highest a Limit can define + public static final int[] VERY_HARD_LIMIT_MIN_BG = {72, 180}; + public static final int[] VERY_HARD_LIMIT_MAX_BG = {90, 270}; + public static final int[] VERY_HARD_LIMIT_TARGET_BG = {80, 200}; + // Very Hard Limits Ranges for Temp Targets + public static final int[] VERY_HARD_LIMIT_TEMP_MIN_BG = {72, 180}; + public static final int[] VERY_HARD_LIMIT_TEMP_MAX_BG = {72, 270}; + public static final int[] VERY_HARD_LIMIT_TEMP_TARGET_BG = {72, 200}; + + public static final double MINDIA = 2; + public static final double MAXDIA = 7; + + public static final double MINIC = 2; + public static final double MAXIC = 100; + + public static final double MINISF = 2; // mgdl + public static final double MAXISF = 720; // mgdl + + public static final double[] MAXIOB_AMA = {3, 5, 7, 7}; + public static final double[] MAXIOB_SMB = {3, 6, 10, 12}; + + public static final double[] MAXBASAL = {2, 5, 10, 12}; + + + private static int loadAge() { + String sp_age = SP.getString(R.string.key_age, ""); + int age; + + if (sp_age.equals(MainApp.sResources.getString(R.string.key_child))) + age = CHILD; + else if (sp_age.equals(MainApp.sResources.getString(R.string.key_teenage))) + age = TEENAGE; + else if (sp_age.equals(MainApp.sResources.getString(R.string.key_adult))) + age = ADULT; + else if (sp_age.equals(MainApp.sResources.getString(R.string.key_resistantadult))) + age = RESISTANTADULT; + else age = ADULT; + + return age; } + public static double maxBolus() { + return MAXBOLUS[loadAge()]; + } + + public static double maxIobAMA() { + return MAXIOB_AMA[loadAge()]; + } + + public static double maxIobSMB() { + return MAXIOB_SMB[loadAge()]; + } + + public static double maxBasal() { + return MAXBASAL[loadAge()]; + } + + // safety checks + public static boolean checkOnlyHardLimits(Double value, String valueName, double lowLimit, double highLimit) { + return value.equals(verifyHardLimits(value, valueName, lowLimit, highLimit)); + } + + public static Double verifyHardLimits(Double value, String valueName, double lowLimit, double highLimit) { + Double newvalue = value; + if (newvalue < lowLimit || newvalue > highLimit) { + newvalue = Math.max(newvalue, lowLimit); + newvalue = Math.min(newvalue, highLimit); + String msg = String.format(MainApp.sResources.getString(R.string.valueoutofrange), valueName); + msg += ".\n"; + msg += String.format(MainApp.sResources.getString(R.string.valuelimitedto), value, newvalue); + log.error(msg); + NSUpload.uploadError(msg); + ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), msg, R.raw.error); + } + return newvalue; + } } diff --git a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java index e74818d447..915d8bfb27 100644 --- a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java +++ b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java @@ -1,9 +1,7 @@ package info.nightscout.utils; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Date; @@ -17,13 +15,14 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.receivers.KeepAliveReceiver; /** * Created by adrian on 17/12/17. */ public class LocalAlertUtils { + private static Logger log = LoggerFactory.getLogger(LocalAlertUtils.class); + public static int missedReadingsThreshold() { return SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30) * 60 * 1000; } @@ -34,14 +33,18 @@ public class LocalAlertUtils { public static void checkPumpUnreachableAlarm(Date lastConnection, boolean isStatusOutdated) { boolean alarmTimeoutExpired = lastConnection.getTime() + pumpUnreachableThreshold() < System.currentTimeMillis(); - boolean nextAlarmOccurrenceReached = SP.getLong("nextPumpDisconnectedAlarm", 0l) < System.currentTimeMillis(); + boolean nextAlarmOccurrenceReached = SP.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis(); if (Config.APS && SP.getBoolean(MainApp.sResources.getString(R.string.key_enable_pump_unreachable_alert), true) && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !ConfigBuilderPlugin.getActiveLoop().isDisconnected()) { + log.debug("Generating pump unreachable alarm. lastConnection: " + DateUtil.dateAndTimeString(lastConnection) + " isStatusOutdated: " + isStatusOutdated); Notification n = new Notification(Notification.PUMP_UNREACHABLE, MainApp.sResources.getString(R.string.pump_unreachable), Notification.URGENT); n.soundId = R.raw.alarm; SP.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + pumpUnreachableThreshold()); MainApp.bus().post(new EventNewNotification(n)); + if (SP.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) { + NSUpload.uploadError(n.text); + } } } @@ -91,6 +94,9 @@ public class LocalAlertUtils { n.soundId = R.raw.alarm; SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold()); MainApp.bus().post(new EventNewNotification(n)); + if (SP.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) { + NSUpload.uploadError(n.text); + } } } } diff --git a/app/src/main/java/info/nightscout/utils/LogDialog.java b/app/src/main/java/info/nightscout/utils/LogDialog.java index 0bd4216163..b98582c05f 100644 --- a/app/src/main/java/info/nightscout/utils/LogDialog.java +++ b/app/src/main/java/info/nightscout/utils/LogDialog.java @@ -7,7 +7,6 @@ import android.content.DialogInterface; import android.content.ClipboardManager; import android.widget.TextView; -import com.crashlytics.android.Crashlytics; import java.io.BufferedReader; import java.io.IOException; diff --git a/app/src/main/java/info/nightscout/utils/NSUpload.java b/app/src/main/java/info/nightscout/utils/NSUpload.java index 2f8893aa7b..690b239128 100644 --- a/app/src/main/java/info/nightscout/utils/NSUpload.java +++ b/app/src/main/java/info/nightscout/utils/NSUpload.java @@ -399,6 +399,7 @@ public class NSUpload { try { data.put("eventType", "Announcement"); data.put("created_at", DateUtil.toISOString(new Date())); + data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name))); data.put("notes", error); data.put("isAnnouncement", true); } catch (JSONException e) { diff --git a/app/src/main/jniLibs/arm64-v8a/libBleCommandUtil.so b/app/src/main/jniLibs/arm64-v8a/libBleCommandUtil.so deleted file mode 100644 index 69e283b5fe..0000000000 Binary files a/app/src/main/jniLibs/arm64-v8a/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libBleCommandUtil.so b/app/src/main/jniLibs/armeabi-v7a/libBleCommandUtil.so deleted file mode 100644 index 0c717bc3e8..0000000000 Binary files a/app/src/main/jniLibs/armeabi-v7a/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/jniLibs/armeabi/libBleCommandUtil.so b/app/src/main/jniLibs/armeabi/libBleCommandUtil.so deleted file mode 100644 index a51a8c7d9a..0000000000 Binary files a/app/src/main/jniLibs/armeabi/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/jniLibs/mips/libBleCommandUtil.so b/app/src/main/jniLibs/mips/libBleCommandUtil.so deleted file mode 100644 index fcff5eb6b2..0000000000 Binary files a/app/src/main/jniLibs/mips/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/jniLibs/mips64/libBleCommandUtil.so b/app/src/main/jniLibs/mips64/libBleCommandUtil.so deleted file mode 100644 index a8a292ea13..0000000000 Binary files a/app/src/main/jniLibs/mips64/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/jniLibs/x86/libBleCommandUtil.so b/app/src/main/jniLibs/x86/libBleCommandUtil.so deleted file mode 100644 index 638a9def95..0000000000 Binary files a/app/src/main/jniLibs/x86/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/jniLibs/x86_64/libBleCommandUtil.so b/app/src/main/jniLibs/x86_64/libBleCommandUtil.so deleted file mode 100644 index 94873d3732..0000000000 Binary files a/app/src/main/jniLibs/x86_64/libBleCommandUtil.so and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/icon_xdrip.png b/app/src/main/res/drawable-hdpi/icon_xdrip.png new file mode 100644 index 0000000000..bda51738e7 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_xdrip.png differ diff --git a/app/src/main/res/drawable-mdpi/icon_xdrip.png b/app/src/main/res/drawable-mdpi/icon_xdrip.png new file mode 100644 index 0000000000..700e274f5b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/icon_xdrip.png differ diff --git a/app/src/main/res/drawable-xhdpi/icon_xdrip.png b/app/src/main/res/drawable-xhdpi/icon_xdrip.png new file mode 100644 index 0000000000..ae4c77b1a8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_xdrip.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_xdrip.png b/app/src/main/res/drawable-xxhdpi/icon_xdrip.png new file mode 100644 index 0000000000..c375417b1c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_xdrip.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_xdrip.png b/app/src/main/res/drawable-xxxhdpi/icon_xdrip.png new file mode 100644 index 0000000000..2b4b8323b8 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_xdrip.png differ diff --git a/app/src/main/res/drawable/ic_chevron_left_black_24dp.xml b/app/src/main/res/drawable/ic_chevron_left_black_24dp.xml new file mode 100644 index 0000000000..e6bb3ca920 --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_left_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_chevron_right_black_24dp.xml b/app/src/main/res/drawable/ic_chevron_right_black_24dp.xml new file mode 100644 index 0000000000..24835127dd --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_right_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_first_page_black_24dp.xml b/app/src/main/res/drawable/ic_first_page_black_24dp.xml new file mode 100644 index 0000000000..483f56c7c2 --- /dev/null +++ b/app/src/main/res/drawable/ic_first_page_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_last_page_black_24dp.xml b/app/src/main/res/drawable/ic_last_page_black_24dp.xml new file mode 100644 index 0000000000..0d04354c14 --- /dev/null +++ b/app/src/main/res/drawable/ic_last_page_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icon_insulin_carbs.xml b/app/src/main/res/drawable/icon_insulin_carbs.xml new file mode 100644 index 0000000000..6dcd511598 --- /dev/null +++ b/app/src/main/res/drawable/icon_insulin_carbs.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_historybrowse.xml b/app/src/main/res/layout/activity_historybrowse.xml new file mode 100644 index 0000000000..a4959eb3f7 --- /dev/null +++ b/app/src/main/res/layout/activity_historybrowse.xml @@ -0,0 +1,214 @@ + + + + + + + + + + + +