diff --git a/.travis.yml b/.travis.yml index 52552b3ceb..73fe4b80d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,12 +7,15 @@ android: components: - platform-tools - tools - - build-tools-26.0.2 + - build-tools-27.0.2 - android-23 - extra-google-m2repository - extra-android-m2repository - extra-google-google_play_services +before_install: +- yes | sdkmanager "platforms;android-27" + script: # Unit Test - ./gradlew test jacocoTestReport diff --git a/app/build.gradle b/app/build.gradle index 84b826e188..67bac2b736 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,9 +12,10 @@ buildscript { apply plugin: "com.android.application" apply plugin: "io.fabric" apply plugin: "jacoco-android" +apply plugin: 'com.jakewharton.butterknife' ext { - supportLibraryVersion = "23.4.0" + supportLibraryVersion = "27.0.2" ormLiteVersion = "4.46" powermockVersion = "1.7.3" dexmakerVersion = "1.2" @@ -47,8 +48,8 @@ def generateGitBuild = { -> } android { - compileSdkVersion 23 - buildToolsVersion "26.0.2" + compileSdkVersion 27 + buildToolsVersion "${supportLibraryVersion}" defaultConfig { applicationId "info.nightscout.androidaps" @@ -65,6 +66,13 @@ android { } } lintOptions { + // TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0 + // has been upgraded (requiring significant code changes), which currently fails release + // build with a deprecation warning + //abortOnError false + // (disabled entirely to avoid reports on the error, which would still be displayed + // and it's easy to overlook that it's ignored) + checkReleaseBuilds false disable 'MissingTranslation' disable 'ExtraTranslation' } @@ -209,6 +217,9 @@ dependencies { compile "net.danlew:android.joda:2.9.9.1" + api "com.jakewharton:butterknife:8.8.1" + annotationProcessor "com.jakewharton:butterknife-compiler:8.8.1" + testCompile "junit:junit:4.12" testCompile "org.json:json:20140107" testCompile "org.mockito:mockito-core:2.7.22" diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index da11d69c61..0b7b1ab9da 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -235,6 +235,10 @@ public class MainApp extends Application { return sResources.getString(id); } + public static String gs(int id, Object... args) { + return sResources.getString(id, args); + } + public static MainApp instance() { return sInstance; } 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 d37693d494..701b226031 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java @@ -35,4 +35,6 @@ public class PumpDescription { public double basalMinimumRate = 0.04d; public boolean isRefillingCapable = false; + + public boolean storesCarbInfo = true; } 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 539b9991a3..b2d79f4b7e 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 @@ -6,7 +6,7 @@ import android.app.PendingIntent; import android.app.TaskStackBuilder; import android.content.Context; import android.content.Intent; -import android.support.v7.app.NotificationCompat; +import android.support.v4.app.NotificationCompat; import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; 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 e8856a54f1..9fffb891e4 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 @@ -158,19 +158,23 @@ public class NewTreatmentDialog extends DialogFragment implements OnClickListene detailedBolusInfo.carbs = finalCarbsAfterConstraints; 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); + if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { + 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); + } } - } - }); + }); + } else { + MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + } Answers.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 530843836d..d74c9caadf 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 @@ -365,19 +365,23 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com detailedBolusInfo.carbTime = carbTime; detailedBolusInfo.boluscalc = boluscalcJSON; 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); + if (detailedBolusInfo.insulin > 0 || ConfigBuilderPlugin.getActivePump().getPumpDescription().storesCarbInfo) { + 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); + } } - } - }); + }); + } else { + MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); + } Answers.getInstance().logCustom(new CustomEvent("Wizard")); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java index 9e631def18..558d01b94d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/PersistentNotificationPlugin.java @@ -7,7 +7,7 @@ import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v4.app.TaskStackBuilder; -import android.support.v7.app.NotificationCompat; +import android.support.v4.app.NotificationCompat; import com.squareup.otto.Subscribe; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java index 7baea350b0..4fb9dd250f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java @@ -106,7 +106,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis builder.setMessage(R.string.combo_read_full_history_confirmation); builder.setPositiveButton(R.string.ok, (dialog, which) -> new Thread(() -> ComboPlugin.getPlugin().readAllPumpData()).start()); - builder.setNegativeButton(MainApp.sResources.getString(R.string.cancel), null); + builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); return true; } @@ -191,7 +191,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis lastConnectionView.setText(R.string.combo_pump_connected_now); lastConnectionView.setTextColor(Color.WHITE); } else if (plugin.getPump().lastSuccessfulCmdTime + 30 * 60 * 1000 < System.currentTimeMillis()) { - lastConnectionView.setText(MainApp.sResources.getString(R.string.combo_no_pump_connection, min)); + lastConnectionView.setText(MainApp.gs(R.string.combo_no_pump_connection, min)); lastConnectionView.setTextColor(Color.RED); } else { lastConnectionView.setText(minAgo); @@ -199,7 +199,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis } // base basal rate - baseBasalRate.setText(MainApp.sResources.getString(R.string.pump_basebasalrate, plugin.getBaseBasalRate())); + baseBasalRate.setText(MainApp.gs(R.string.pump_basebasalrate, plugin.getBaseBasalRate())); // TBR String tbrStr = ""; @@ -207,7 +207,7 @@ public class ComboFragment extends SubscriberFragment implements View.OnClickLis long minSinceRead = (System.currentTimeMillis() - plugin.getPump().state.timestamp) / 1000 / 60; long remaining = ps.tbrRemainingDuration - minSinceRead; if (remaining >= 0) { - tbrStr = MainApp.sResources.getString(R.string.combo_tbr_remaining, ps.tbrPercent, remaining); + tbrStr = MainApp.gs(R.string.combo_tbr_remaining, ps.tbrPercent, remaining); } } tempBasalText.setText(tbrStr); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index 32a91a7a73..13e208774f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -89,6 +89,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf pumpDescription.basalMinimumRate = 0.05d; pumpDescription.isRefillingCapable = true; + + pumpDescription.storesCarbInfo = false; } @NonNull @@ -126,12 +128,12 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf @Override public String getName() { - return MainApp.instance().getString(R.string.combopump); + return MainApp.gs(R.string.combopump); } @Override public String getNameShort() { - String name = MainApp.sResources.getString(R.string.combopump_shortname); + String name = MainApp.gs(R.string.combopump_shortname); if (!name.trim().isEmpty()) { //only if translation exists return name; @@ -143,18 +145,18 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf String getStateSummary() { PumpState ps = pump.state; if (!validBasalRateProfileSelectedOnPump) { - return MainApp.sResources.getString(R.string.loopdisabled); + return MainApp.gs(R.string.loopdisabled); } else if (ps.activeAlert != null) { return ps.activeAlert.errorCode != null ? "E" + ps.activeAlert.errorCode + ": " + ps.activeAlert.message : "W" + ps.activeAlert.warningCode + ": " + ps.activeAlert.message; } else if (ps.menu == null) - return MainApp.sResources.getString(R.string.combo_pump_state_disconnected); + return MainApp.gs(R.string.combo_pump_state_disconnected); else if (ps.suspended && (ps.batteryState == PumpState.EMPTY || ps.insulinState == PumpState.EMPTY)) - return MainApp.sResources.getString(R.string.combo_pump_state_suspended_due_to_error); + return MainApp.gs(R.string.combo_pump_state_suspended_due_to_error); else if (ps.suspended) - return MainApp.sResources.getString(R.string.combo_pump_state_suspended_by_user); - return MainApp.sResources.getString(R.string.combo_pump_state_running); + return MainApp.gs(R.string.combo_pump_state_suspended_by_user); + return MainApp.gs(R.string.combo_pump_state_running); } @Override @@ -231,7 +233,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf @Override public void connect(String reason) { - // ruffyscripter establishes a connection as needed + // ruffyscripter establishes a connection as needed. + // ComboPlugin.runCommand performs on connect checks if needed, thus needs info on + // whether a connection is there. + // More importantly, RuffyScripter needs control over connection to be able to recover + // from a failure and deal with alarms on pump. + // Yes, this could also be done by keeping a flag 'inCmd' in RuffyScripter, which kicks + // off recovery unless set to false again after command completion and have connect + // checks be called in ComboPlugin.connect(); ... and have that cause other issues } @Override @@ -251,9 +260,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // note that this should not happen anymore since the queue is present, which // issues a READSTATE when starting to issue commands which initializes the pump log.error("setNewBasalProfile not initialized"); - Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); + Notification notification = new Notification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED, MainApp.gs(R.string.pumpNotInitializedProfileNotSet), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); - return new PumpEnactResult().success(false).enacted(false).comment(MainApp.sResources.getString(R.string.pumpNotInitializedProfileNotSet)); + return new PumpEnactResult().success(false).enacted(false).comment(MainApp.gs(R.string.pumpNotInitializedProfileNotSet)); } BasalProfile requestedBasalProfile = convertProfileToComboProfile(profile); @@ -266,29 +275,24 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf CommandResult stateResult = runCommand(null, 1, ruffyScripter::readPumpState); if (stateResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) { - return new PumpEnactResult().success(false).enacted(false).comment(MainApp.sResources.getString(R.string.combo_force_disabled_notification)); + return new PumpEnactResult().success(false).enacted(false).comment(MainApp.gs(R.string.combo_force_disabled_notification)); } - CommandResult setResult = runCommand(MainApp.sResources.getString(R.string.combo_activity_setting_basal_profile), 2, + CommandResult setResult = runCommand(MainApp.gs(R.string.combo_activity_setting_basal_profile), 2, () -> ruffyScripter.setBasalProfile(requestedBasalProfile)); if (!setResult.success) { - Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.sResources.getString(R.string.failedupdatebasalprofile), Notification.URGENT); + Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, MainApp.gs(R.string.failedupdatebasalprofile), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); - return new PumpEnactResult().success(false).enacted(false).comment(MainApp.sResources.getString(R.string.failedupdatebasalprofile)); + return new PumpEnactResult().success(false).enacted(false).comment(MainApp.gs(R.string.failedupdatebasalprofile)); } -/* don't re-read basal profile to not trigger pump bug; setBasalProfile command checks the total at the end, which must suffice - CommandResult readResult = runCommand(MainApp.sResources.getString(R.string.combo_activity_setting_basal_profile), 2, - ruffyScripter::readBasalProfile); -*/ - pump.basalProfile = requestedBasalProfile; //dismiss previously "FAILED" overview notifications MainApp.bus().post(new EventDismissNotification(Notification.PROFILE_NOT_SET_NOT_INITIALIZED)); MainApp.bus().post(new EventDismissNotification(Notification.FAILED_UDPATE_PROFILE)); //issue success notification - Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.sResources.getString(R.string.profile_set_ok), Notification.INFO, 60); + Notification notification = new Notification(Notification.PROFILE_SET_OK, MainApp.gs(R.string.profile_set_ok), Notification.INFO, 60); MainApp.bus().post(new EventNewNotification(notification)); return new PumpEnactResult().success(true).enacted(true); } @@ -342,7 +346,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (!pump.initialized) { initializePump(); } else { - runCommand(MainApp.sResources.getString(R.string.combo_pump_action_refreshing), 1, ruffyScripter::readPumpState); + runCommand(MainApp.gs(R.string.combo_pump_action_refreshing), 1, ruffyScripter::readPumpState); } } @@ -359,14 +363,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } } - CommandResult stateResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_initializing),1, ruffyScripter::readPumpState); + CommandResult stateResult = runCommand(MainApp.gs(R.string.combo_pump_action_initializing),1, ruffyScripter::readPumpState); if (!stateResult.success) { return; } if (stateResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) { Notification n = new Notification(Notification.COMBO_PUMP_ALARM, - MainApp.sResources.getString(R.string.combo_force_disabled_notification), + MainApp.gs(R.string.combo_force_disabled_notification), Notification.URGENT); n.soundId = R.raw.alarm; MainApp.bus().post(new EventNewNotification(n)); @@ -374,7 +378,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } // read basal profile into cache (KeepAlive will trigger a profile update if needed) - CommandResult readBasalResult = runCommand("Reading basal profile", 2, ruffyScripter::readBasalProfile); + CommandResult readBasalResult = runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile); if (!readBasalResult.success) { return; } @@ -383,7 +387,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf pump.initialized = true; MainApp.bus().post(new EventInitializationChanged()); - // ComboFragment updates state fully only after the pump has initialized, so run this manually here + // ComboFragment updates state fully only after the pump has initialized, so read full state here updateLocalData(readBasalResult); } @@ -407,22 +411,22 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance(); switch (state) { case PROGRAMMING: - event.status = MainApp.sResources.getString(R.string.combo_programming_bolus); + event.status = MainApp.gs(R.string.combo_programming_bolus); break; case DELIVERING: - event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), delivered); + event.status = MainApp.gs(R.string.bolusdelivering, delivered); break; case DELIVERED: - event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), delivered); + event.status = MainApp.gs(R.string.bolusdelivered, delivered); break; case STOPPING: - event.status = MainApp.sResources.getString(R.string.bolusstopping); + event.status = MainApp.gs(R.string.bolusstopping); break; case STOPPED: - event.status = MainApp.sResources.getString(R.string.bolusstopped); + event.status = MainApp.gs(R.string.bolusstopped); break; case RECOVERING: - event.status = MainApp.sResources.getString(R.string.combo_error_bolus_recovery_progress); + event.status = MainApp.gs(R.string.combo_error_bolus_recovery_progress); } event.percent = percent; MainApp.bus().post(event); @@ -468,7 +472,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf && lastRequestedBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) { log.error("Bolus delivery failure at stage 0", new Exception()); return new PumpEnactResult().success(false).enacted(false) - .comment(MainApp.sResources.getString(R.string.bolus_frequency_exceeded)); + .comment(MainApp.gs(R.string.bolus_frequency_exceeded)); } lastRequestedBolus = new Bolus(System.currentTimeMillis(), detailedBolusInfo.insulin, true); @@ -476,11 +480,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf long pumpTimeWhenBolusWasRequested = stateResult .state.pumpTime; if (!stateResult.success || pumpTimeWhenBolusWasRequested == 0) { return new PumpEnactResult().success(false).enacted(false) - .comment(MainApp.sResources.getString(R.string.combo_error_no_bolus_delivered)); + .comment(MainApp.gs(R.string.combo_error_no_bolus_delivered)); } try { - pump.activity = MainApp.sResources.getString(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin); + pump.activity = MainApp.gs(R.string.combo_pump_action_bolusing, detailedBolusInfo.insulin); MainApp.bus().post(new EventComboPumpUpdateGUI()); if (cancelBolus) { @@ -539,7 +543,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // this happens when the cartridge runs empty during delivery, the pump will be in an error // state with multiple alarms ringing and no chance of reading history return new PumpEnactResult().success(false).enacted(false) - .comment(MainApp.sResources.getString(R.string.combo_error_bolus_verification_failed)); + .comment(MainApp.gs(R.string.combo_error_bolus_verification_failed)); } List bolusHistory = readLastBolusResult.history.bolusHistory; @@ -553,7 +557,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf || !lastBolus.isValid) { // ext/multiwave bolus log.debug("No bolus was delivered"); return new PumpEnactResult().success(false).enacted(false) - .comment(MainApp.sResources.getString(R.string.combo_error_no_bolus_delivered)); + .comment(MainApp.gs(R.string.combo_error_no_bolus_delivered)); } else if (Math.abs(lastBolus.amount - detailedBolusInfo.insulin) > 0.01) { // bolus only partially delivered double requestedBolus = detailedBolusInfo.insulin; @@ -563,7 +567,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf log.debug(String.format(Locale.getDefault(), "Added partial bolus of %.2f to treatments (requested: %.2f)", lastBolus.amount, requestedBolus)); return new PumpEnactResult().success(false).enacted(true) - .comment(MainApp.sResources.getString(R.string.combo_error_partial_bolus_delivered, + .comment(MainApp.gs(R.string.combo_error_partial_bolus_delivered, lastBolus.amount, requestedBolus)); } else { // bolus was correctly and fully delivered @@ -635,7 +639,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } int finalAdjustedPercent = adjustedPercent; - CommandResult commandResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_setting_tbr, percent, durationInMinutes), + CommandResult commandResult = runCommand(MainApp.gs(R.string.combo_pump_action_setting_tbr, percent, durationInMinutes), 3, () -> ruffyScripter.setTbr(finalAdjustedPercent, durationInMinutes)); if (!commandResult.success) { return new PumpEnactResult().success(false).enacted(false); @@ -670,7 +674,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); if (userRequested) { log.debug("cancelTempBasal: hard-cancelling TBR since user requested"); - CommandResult commandResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_cancelling_tbr), 2, ruffyScripter::cancelTbr); + CommandResult commandResult = runCommand(MainApp.gs(R.string.combo_pump_action_cancelling_tbr), 2, ruffyScripter::cancelTbr); if (!commandResult.state.tbrActive) { TemporaryBasal tempBasal = new TemporaryBasal(); tempBasal.date = commandResult.state.timestamp; @@ -744,7 +748,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf if (validBasalRateProfileSelectedOnPump && commandResult.state.unsafeUsageDetected == PumpState.UNSUPPORTED_BASAL_RATE_PROFILE) { validBasalRateProfileSelectedOnPump = false; Notification n = new Notification(Notification.COMBO_PUMP_ALARM, - MainApp.sResources.getString(R.string.combo_force_disabled_notification), + MainApp.gs(R.string.combo_force_disabled_notification), Notification.URGENT); n.soundId = R.raw.alarm; MainApp.bus().post(new EventNewNotification(n)); @@ -791,7 +795,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf notification.date = new Date(); notification.id = Notification.COMBO_PUMP_ALARM; notification.level = Notification.URGENT; - notification.text = MainApp.sResources.getString(R.string.combo_is_in_error_state, activeAlert.errorCode, activeAlert.message); + notification.text = MainApp.gs(R.string.combo_is_in_error_state, activeAlert.errorCode, activeAlert.message); MainApp.bus().post(new EventNewNotification(notification)); return preCheckResult.success(false); } @@ -810,11 +814,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field) } else if (Math.abs(state.pumpTime - System.currentTimeMillis()) >= 10 * 60 * 1000) { log.debug("Pump clock needs update, pump time: " + state.pumpTime + " (" + new Date(state.pumpTime) + ")"); - Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.sResources.getString(R.string.combo_notification_check_time_date), Notification.URGENT); + Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_notification_check_time_date), Notification.URGENT); MainApp.bus().post(new EventNewNotification(notification)); } else if (Math.abs(state.pumpTime - System.currentTimeMillis()) >= 3 * 60 * 1000) { log.debug("Pump clock needs update, pump time: " + state.pumpTime + " (" + new Date(state.pumpTime) + ")"); - Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.sResources.getString(R.string.combo_notification_check_time_date), Notification.NORMAL); + Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, MainApp.gs(R.string.combo_notification_check_time_date), Notification.NORMAL); MainApp.bus().post(new EventNewNotification(notification)); } } @@ -831,11 +835,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf notification.id = Notification.COMBO_PUMP_ALARM; notification.level = Notification.NORMAL; if (activeAlert.warningCode == PumpWarningCodes.CARTRIDGE_LOW) { - notification.text = MainApp.sResources.getString(R.string.combo_pump_cartridge_low_warrning); + notification.text = MainApp.gs(R.string.combo_pump_cartridge_low_warrning); } else if (activeAlert.warningCode == PumpWarningCodes.BATTERY_LOW) { - notification.text = MainApp.sResources.getString(R.string.combo_pump_battery_low_warrning); + notification.text = MainApp.gs(R.string.combo_pump_battery_low_warrning); } else if (activeAlert.warningCode == PumpWarningCodes.TBR_CANCELLED) { - notification.text = MainApp.sResources.getString(R.string.combo_pump_tbr_cancelled_warrning); + notification.text = MainApp.gs(R.string.combo_pump_tbr_cancelled_warrning); } MainApp.bus().post(new EventNewNotification(notification)); } @@ -859,7 +863,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf lowSuspendOnlyLoopEnforcedUntil = lastViolation + 6 * 60 * 60 * 1000; if (lowSuspendOnlyLoopEnforcedUntil > System.currentTimeMillis() && violationWarningRaisedForBolusAt != lowSuspendOnlyLoopEnforcedUntil) { Notification n = new Notification(Notification.COMBO_PUMP_ALARM, - MainApp.sResources.getString(R.string.combo_low_suspend_forced_notification), + MainApp.gs(R.string.combo_low_suspend_forced_notification), Notification.URGENT); n.soundId = R.raw.alarm; MainApp.bus().post(new EventNewNotification(n)); @@ -919,7 +923,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf * which warns the user against doing this. */ private boolean readHistory(final PumpHistoryRequest request) { - CommandResult historyResult = runCommand(MainApp.sResources.getString(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request)); + CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request)); if (!historyResult.success) { return false; } @@ -1007,7 +1011,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } */ - CommandResult basalResult = runCommand("Reading basal profile", 2, ruffyScripter::readBasalProfile); + CommandResult basalResult = runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile); if (!basalResult.success) { return; } 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 4ba660db66..3a11ebe0a6 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 @@ -110,6 +110,8 @@ public class DanaRPlugin implements PluginBase, PumpInterface, DanaRInterface, C pumpDescription.basalMinimumRate = 0.04d; pumpDescription.isRefillingCapable = true; + + pumpDescription.storesCarbInfo = true; } private ServiceConnection mConnection = new ServiceConnection() { 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 f269aff112..e92febada6 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 @@ -112,6 +112,8 @@ public class DanaRKoreanPlugin implements PluginBase, PumpInterface, DanaRInterf pumpDescription.basalMinimumRate = 0.1d; pumpDescription.isRefillingCapable = true; + + pumpDescription.storesCarbInfo = true; } private ServiceConnection mConnection = new ServiceConnection() { 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 ed9f98651f..cfdbdeb5cd 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 @@ -189,6 +189,8 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, pumpDescription.basalMinimumRate = 0.04d; pumpDescription.isRefillingCapable = true; + + pumpDescription.storesCarbInfo = true; } private ServiceConnection mConnection = new ServiceConnection() { @@ -477,7 +479,7 @@ public class DanaRSPlugin implements PluginBase, PumpInterface, DanaRInterface, Treatment t = new Treatment(); boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) - connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 1000, t); // +1000 to make the record different + connectionOK = danaRSService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 30000, t); // +30s to make the record different PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; 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 b4eb969852..3e1aca22e0 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 @@ -109,6 +109,8 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, pumpDescription.basalMinimumRate = 0.04d; pumpDescription.isRefillingCapable = true; + + pumpDescription.storesCarbInfo = true; } private ServiceConnection mConnection = new ServiceConnection() { @@ -329,7 +331,7 @@ public class DanaRv2Plugin implements PluginBase, PumpInterface, DanaRInterface, Treatment t = new Treatment(); boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) - connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 1000, t); // +1000 to make the record different + connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, System.currentTimeMillis() + carbTime * 60 * 1000 + 30000, t); // +30s to make the record different PumpEnactResult result = new PumpEnactResult(); result.success = connectionOK; result.bolusDelivered = t.insulin; diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f3b5aaef86..7c033bc908 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -778,5 +778,6 @@ Standarwert: 2\nBolus snooze (\"Bolus-Schlummer\") bremst den Loop nach einem Mahleiten-Bolus, damit dieser nicht mit niedrigen TBR reagiert, wenn Du gerade gegessen hast. Beispiel: Der Standardwert 2 bewirkt, dass bei einem 3 Stunden DIA der Bolus snooze während 1.5 Stunden nach dem Bolus linear ausläuft (3 h Dia / 2 = 1.5 h Bolus snooze). Standardwert: 3.0\nDies ist eine Einstellung für die Standard-Kohlenhydrat-Absorptionswirkung pro 5 Minuten. Der Standardwert ist 3mg/dl/5min. Dies wirkt sich darauf aus, wie schnell der COB-Wert fällt und wieviel KH-Absorption bei der Berechnung des vorhergesagten BZ angenommen wird, wenn der BZ stärker als erwartet fällt oder nicht so stark wie erwartet steigt. Achtung! Normalerweise musst Du diese Werte nicht ändern. Bitte KLICKE HIER und LESE den Text. Verändere Werte erst, wenn Du den Inhalt des Textes verstanden hast. - %2.f IE/h + %.2f IE/h + Basalratenprofil wird gelesen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 7259194dee..988a92928d 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -231,8 +231,8 @@ XXXXXXXXXX +; + YYYYYYYYYY Para entregar bolo% .2fU responder con código% s Bolo falló - Bolo% .2fU entregado con éxito - Entregando% .2fU + Bolo %.2fU entregado con éxito + Entregando %.2fU Bolo remoto no permitido Dedo Sensor diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 24be3e6519..45d34c5172 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -864,5 +864,6 @@ Not enough insulin for bolus left in reservoir Extended bolus delivery error %.2f U/h + Reading basal profile diff --git a/build.gradle b/build.gradle index 7e01a0aa59..e13cb27485 100644 --- a/build.gradle +++ b/build.gradle @@ -10,13 +10,17 @@ buildscript { // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files + + classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0' } } allprojects { repositories { jcenter() - google() + maven { + url "https://maven.google.com" + } } }