diff --git a/.gitignore b/.gitignore index 7dc3c7a865..98b73cb7cb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ build/ app/src/main/jniLibs full/ debug/ -release/ \ No newline at end of file +release/ +app/com.crashlytics.settings.json +app/session_analytics.tap \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 07e057b0fa..ebc87f8a94 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,7 +63,7 @@ android { targetSdkVersion 25 multiDexEnabled true versionCode 1500 - version "2.0b-dev" + version "2.0c-dev" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 5ef716bad9..cf8ff788e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -698,7 +698,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { .duration(trJson.getInt("duration")) .low(Profile.toMgdl(trJson.getDouble("targetBottom"), units)) .high(Profile.toMgdl(trJson.getDouble("targetTop"), units)) - .reason(trJson.getString("reason")) + .reason(JsonHelper.safeGetString(trJson, "reason", "")) ._id(trJson.getString("_id")) .source(Source.NIGHTSCOUT); createOrUpdate(tempTarget); diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventAcceptOpenLoopChange.java b/app/src/main/java/info/nightscout/androidaps/events/EventAcceptOpenLoopChange.java new file mode 100644 index 0000000000..2dfbf9ae35 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/events/EventAcceptOpenLoopChange.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.events; + +/** Base class for events to update the UI, mostly a specific tab. */ +public class EventAcceptOpenLoopChange extends Event { +} diff --git a/app/src/main/java/info/nightscout/androidaps/logging/L.java b/app/src/main/java/info/nightscout/androidaps/logging/L.java index 60d6ff4602..4b8b9d99f1 100644 --- a/app/src/main/java/info/nightscout/androidaps/logging/L.java +++ b/app/src/main/java/info/nightscout/androidaps/logging/L.java @@ -81,7 +81,6 @@ public class L { public static final String BGSOURCE = "BGSOURCE"; public static final String OVERVIEW = "OVERVIEW"; public static final String NOTIFICATION = "NOTIFICATION"; - public static final String ALARM = "ALARM"; public static final String DATASERVICE = "DATASERVICE"; public static final String DATABASE = "DATABASE"; public static final String DATAFOOD = "DATAFOOD"; @@ -98,7 +97,6 @@ public class L { private static void initialize() { logElements = new ArrayList<>(); - logElements.add(new LogElement(ALARM, false)); logElements.add(new LogElement(APS, true)); logElements.add(new LogElement(AUTOSENS, false)); logElements.add(new LogElement(BGSOURCE, 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 d82b010450..c9fdb45f86 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 @@ -44,6 +44,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.Loop.events.EventLoopSetLastRunGui; @@ -51,6 +52,8 @@ import info.nightscout.androidaps.plugins.Loop.events.EventLoopUpdateGui; import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification; import info.nightscout.androidaps.plugins.NSClientInternal.NSUpload; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; +import info.nightscout.androidaps.plugins.Wear.ActionStringHandler; +import info.nightscout.androidaps.events.EventAcceptOpenLoopChange; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.commands.Command; import info.nightscout.utils.FabricPrivacy; @@ -396,7 +399,8 @@ public class LoopPlugin extends PluginBase { .setAutoCancel(true) .setPriority(Notification.PRIORITY_HIGH) .setCategory(Notification.CATEGORY_ALARM) - .setVisibility(Notification.VISIBILITY_PUBLIC); + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setLocalOnly(true); // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(MainApp.instance().getApplicationContext(), MainActivity.class); @@ -418,6 +422,15 @@ public class LoopPlugin extends PluginBase { // mId allows you to update the notification later on. mNotificationManager.notify(Constants.notificationID, builder.build()); MainApp.bus().post(new EventNewOpenLoopNotification()); + + // Send to Wear + ActionStringHandler.handleInitiate("changeRequest"); + } else if (allowNotification) { + // dismiss notifications + NotificationManager notificationManager = + (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(Constants.notificationID); + ActionStringHandler.handleInitiate("cancelChangeRequest"); } } @@ -428,6 +441,29 @@ public class LoopPlugin extends PluginBase { } } + public void acceptChangeRequest() { + Profile profile = ProfileFunctions.getInstance().getProfile(); + + applyTBRRequest(lastRun.constraintsProcessed, profile, new Callback() { + @Override + public void run() { + if (result.enacted) { + lastRun.tbrSetByPump = result; + lastRun.lastEnact = new Date(); + lastRun.lastOpenModeAccept = new Date(); + NSUpload.uploadDeviceStatus(); + ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class); + if (objectivesPlugin != null) { + ObjectivesPlugin.manualEnacts++; + ObjectivesPlugin.saveProgress(); + } + } + MainApp.bus().post(new EventAcceptOpenLoopChange()); + } + }); + FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp")); + } + /** * expect absolute request and allow both absolute and percent response based on pump capabilities */ diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java index 64e2091eb8..9eff2ca84c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientFragment.java @@ -131,9 +131,7 @@ public class NSClientFragment extends SubscriberFragment implements View.OnClick public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { switch (buttonView.getId()) { case R.id.nsclientinternal_paused: - SP.putBoolean(R.string.key_nsclientinternal_paused, isChecked); - NSClientPlugin.getPlugin().paused = isChecked; - MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); + NSClientPlugin.getPlugin().pause(isChecked); updateGUI(); FabricPrivacy.getInstance().logCustom(new CustomEvent("NSClientPause")); break; @@ -154,19 +152,17 @@ public class NSClientFragment extends SubscriberFragment implements View.OnClick protected void updateGUI() { Activity activity = getActivity(); if (activity != null) - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - NSClientPlugin.getPlugin().updateLog(); - logTextView.setText(NSClientPlugin.getPlugin().textLog); - if (NSClientPlugin.getPlugin().autoscroll) { - logScrollview.fullScroll(ScrollView.FOCUS_DOWN); - } - urlTextView.setText(NSClientPlugin.getPlugin().url()); - Spanned queuetext = Html.fromHtml(MainApp.gs(R.string.queue) + " " + UploadQueue.size() + ""); - queueTextView.setText(queuetext); - statusTextView.setText(NSClientPlugin.getPlugin().status); + activity.runOnUiThread(() -> { + NSClientPlugin.getPlugin().updateLog(); + pausedCheckbox.setChecked(SP.getBoolean(R.string.key_nsclientinternal_paused, false)); + logTextView.setText(NSClientPlugin.getPlugin().textLog); + if (NSClientPlugin.getPlugin().autoscroll) { + logScrollview.fullScroll(ScrollView.FOCUS_DOWN); } + urlTextView.setText(NSClientPlugin.getPlugin().url()); + Spanned queuetext = Html.fromHtml(MainApp.gs(R.string.queue) + " " + UploadQueue.size() + ""); + queueTextView.setText(queuetext); + statusTextView.setText(NSClientPlugin.getPlugin().status); }); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java index cc9d843368..3d5a904525 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/NSClientInternal/NSClientPlugin.java @@ -209,6 +209,12 @@ public class NSClientPlugin extends PluginBase { nsClientService.resend(reason); } + public void pause(boolean newState) { + SP.putBoolean(R.string.key_nsclientinternal_paused, newState); + paused = newState; + MainApp.bus().post(new EventPreferenceChange(R.string.key_nsclientinternal_paused)); + } + public UploadQueue queue() { return NSClientService.uploadQueue; } 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 d7066705b9..0c559538e7 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 @@ -8,6 +8,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.PowerManager; +import android.os.SystemClock; import com.google.common.base.Charsets; import com.google.common.hash.Hashing; @@ -22,6 +23,7 @@ import org.slf4j.LoggerFactory; import java.net.URISyntaxException; import java.sql.SQLException; +import java.util.ArrayList; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; @@ -57,6 +59,7 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSTreatment; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientNewLog; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientRestart; import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientStatus; +import info.nightscout.androidaps.plugins.NSClientInternal.events.EventNSClientUpdateGUI; import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.Overview.notifications.Notification; @@ -64,6 +67,7 @@ import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.JsonHelper; import info.nightscout.utils.SP; +import info.nightscout.utils.T; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; @@ -102,6 +106,11 @@ public class NSClientService extends Service { public static UploadQueue uploadQueue = new UploadQueue(); + private ArrayList reconnections = new ArrayList<>(); + private int WATCHDOG_INTERVAL_MINUTES = 2; + private int WATCHDOG_RECONNECT_IN = 1; + private int WATCHDOG_MAXCONNECTIONS = 5; + public NSClientService() { registerBus(); if (handler == null) { @@ -161,8 +170,6 @@ public class NSClientService extends Service { destroy(); stopSelf(); - if (L.isEnabled(L.NSCLIENT)) - log.debug("EventAppExit finished"); } @Subscribe @@ -243,9 +250,36 @@ public class NSClientService extends Service { connectCounter++; MainApp.bus().post(new EventNSClientNewLog("NSCLIENT", "connect #" + connectCounter + " event. ID: " + mSocket.id())); sendAuthMessage(new NSAuthAck()); + watchdog(); } }; + void watchdog() { + synchronized (reconnections) { + long now = DateUtil.now(); + reconnections.add(now); + for (int i = 0; i < reconnections.size(); i++) { + Long r = reconnections.get(i); + if (r < now - T.mins(WATCHDOG_INTERVAL_MINUTES).msecs()) { + reconnections.remove(r); + } + } + MainApp.bus().post(new EventNSClientNewLog("WATCHDOG", "connections in last " + WATCHDOG_INTERVAL_MINUTES + " mins: " + reconnections.size() + "/" + WATCHDOG_MAXCONNECTIONS)); + if (reconnections.size() >= WATCHDOG_MAXCONNECTIONS) { + Notification n = new Notification(Notification.NSMALFUNCTION, MainApp.gs(R.string.nsmalfunction), Notification.URGENT); + MainApp.bus().post(new EventNewNotification(n)); + MainApp.bus().post(new EventNSClientNewLog("WATCHDOG", "pausing for " + WATCHDOG_RECONNECT_IN + " mins")); + NSClientPlugin.getPlugin().pause(true); + MainApp.bus().post(new EventNSClientUpdateGUI()); + new Thread(() -> { + SystemClock.sleep(T.mins(WATCHDOG_RECONNECT_IN).msecs()); + MainApp.bus().post(new EventNSClientNewLog("WATCHDOG", "reenabling NSClient")); + NSClientPlugin.getPlugin().pause(false); + }).start(); + } + } + } + private Emitter.Listener onDisconnect = new Emitter.Listener() { @Override public void call(Object... args) { 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 6fc1e8d5dd..3697bbd1a0 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 @@ -110,6 +110,8 @@ import info.nightscout.androidaps.plugins.Source.SourceDexcomG5Plugin; import info.nightscout.androidaps.plugins.Source.SourceXdripPlugin; import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileViewerDialog; +import info.nightscout.androidaps.plugins.Wear.ActionStringHandler; +import info.nightscout.androidaps.events.EventAcceptOpenLoopChange; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; @@ -741,24 +743,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, builder.setPositiveButton(MainApp.gs(R.string.ok), (dialog, id) -> { hideTempRecommendation(); clearNotification(); - LoopPlugin.getPlugin().applyTBRRequest(finalLastRun.constraintsProcessed, profile, new Callback() { - @Override - public void run() { - if (result.enacted) { - finalLastRun.tbrSetByPump = result; - finalLastRun.lastEnact = new Date(); - finalLastRun.lastOpenModeAccept = new Date(); - NSUpload.uploadDeviceStatus(); - ObjectivesPlugin objectivesPlugin = MainApp.getSpecificPlugin(ObjectivesPlugin.class); - if (objectivesPlugin != null) { - ObjectivesPlugin.manualEnacts++; - ObjectivesPlugin.saveProgress(); - } - } - scheduleUpdateGUI("onClickAcceptTemp"); - } - }); - FabricPrivacy.getInstance().logCustom(new CustomEvent("AcceptTemp")); + LoopPlugin.getPlugin().acceptChangeRequest(); }); builder.setNegativeButton(MainApp.gs(R.string.cancel), null); builder.show(); @@ -958,6 +943,11 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, scheduleUpdateGUI("EventNewOpenLoopNotification"); } + @Subscribe + public void onStatusEvent(final EventAcceptOpenLoopChange ev) { + scheduleUpdateGUI("EventAcceptOpenLoopChange"); + } + @Subscribe public void onStatusEvent(final EventTempTargetChange ev) { scheduleUpdateGUI("EventTempTargetChange"); @@ -998,6 +988,8 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, NotificationManager notificationManager = (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancel(Constants.notificationID); + + ActionStringHandler.handleInitiate("cancelChangeRequest"); } private void updatePumpStatus(String status) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java index 57e6b72377..036faf4a6f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/notifications/Notification.java @@ -65,6 +65,7 @@ public class Notification { public static final int PERMISSION_BATTERY = 37; public static final int PERMISSION_SMS = 38; public static final int MAXIMUM_BASAL_VALUE_REPLACED = 39; + public static final int NSMALFUNCTION = 40; public int id; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java index fad1147dfc..56b3a2cd09 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Persistentnotification/DummyService.java @@ -6,10 +6,21 @@ import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; +import com.squareup.otto.Subscribe; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.events.EventAppExit; +import info.nightscout.androidaps.logging.L; + /** * Keeps AndroidAPS in foreground state, so it won't be terminated by Android nor get restricted by the background execution limits */ public class DummyService extends Service { + private static Logger log = LoggerFactory.getLogger(L.CORE); + @Nullable @Override public IBinder onBind(Intent intent) { @@ -24,8 +35,24 @@ public class DummyService extends Service { return START_STICKY; } + @Subscribe + public void onStatusEvent(EventAppExit event) { + if (L.isEnabled(L.CORE)) + log.debug("EventAppExit received"); + + stopSelf(); + } + + @Override + public void onCreate() { + MainApp.bus().register(this); + } + @Override public void onDestroy() { + if (L.isEnabled(L.CORE)) + log.debug("onDestroy"); + MainApp.bus().unregister(this); stopForeground(true); } } 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 446913b1b8..b1d8ec44bb 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 @@ -412,8 +412,6 @@ public class DanaRExecutionService extends AbstractDanaRExecutionService { MainApp.instance().getApplicationContext().unregisterReceiver(receiver); stopSelf(); - if (L.isEnabled(L.PUMP)) - log.debug("EventAppExit finished"); } public PumpEnactResult setUserOptions() { 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 4be6cee2c1..a52d5d1d1f 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 @@ -93,9 +93,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { MainApp.instance().getApplicationContext().unregisterReceiver(receiver); stopSelf(); - if (L.isEnabled(L.PUMP)) - log.debug("EventAppExit finished"); - } + } @Subscribe public void onStatusEvent(final EventPreferenceChange pch) { 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 932c9c747e..b370ab5711 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 @@ -526,8 +526,6 @@ public class DanaRSService extends Service { log.debug("EventAppExit received"); stopSelf(); - if (L.isEnabled(L.PUMP)) - log.debug("EventAppExit finished"); } void waitForWholeMinute() { 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 1e1147c849..7dfa5aa1f7 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 @@ -112,9 +112,7 @@ public class DanaRv2ExecutionService extends AbstractDanaRExecutionService { MainApp.instance().getApplicationContext().unregisterReceiver(receiver); stopSelf(); - if (L.isEnabled(L.PUMP)) - log.debug("EventAppExit finished"); - } + } @Subscribe public void onStatusEvent(final EventPreferenceChange pch) { 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 6e99f28c12..bb9c7aeae0 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 @@ -33,6 +33,7 @@ import info.nightscout.androidaps.events.EventReloadProfileSwitchData; import info.nightscout.androidaps.events.EventReloadTempBasalData; import info.nightscout.androidaps.events.EventReloadTreatmentData; import info.nightscout.androidaps.events.EventTempTargetChange; +import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; @@ -181,6 +182,10 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface if (profile == null) return total; + InsulinInterface insulinInterface = MainApp.getConfigBuilder().getActiveInsulin(); + if (insulinInterface == null) + return total; + double dia = profile.getDia(); synchronized (treatments) { @@ -364,6 +369,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface public IobTotal getCalculationToTimeTempBasals(long time, Profile profile, boolean truncate, long truncateTime) { IobTotal total = new IobTotal(time); + + InsulinInterface insulinInterface = MainApp.getConfigBuilder().getActiveInsulin(); + if (insulinInterface == null) + return total; + synchronized (tempBasals) { for (Integer pos = 0; pos < tempBasals.size(); pos++) { TemporaryBasal t = tempBasals.get(pos); 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 84e32ca087..0fd1c557b1 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,7 @@ package info.nightscout.androidaps.plugins.Wear; +import android.app.NotificationManager; +import android.content.Context; import android.os.HandlerThread; import android.support.annotation.NonNull; @@ -353,6 +355,23 @@ public class ActionStringHandler { } rAction += "ecarbs " + carbsAfterConstraints + " " + starttimestamp + " " + duration; + } else if ("changeRequest".equals(act[0])) { + ////////////////////////////////////////////// CHANGE REQUEST + rTitle = MainApp.gs(R.string.openloop_newsuggestion); + rAction = "changeRequest"; + final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun; + rMessage += finalLastRun.constraintsProcessed; + + WearPlugin.getPlugin().requestChangeConfirmation(rTitle, rMessage, rAction); + lastSentTimestamp = System.currentTimeMillis(); + lastConfirmActionString = rAction; + return; + } else if ("cancelChangeRequest".equals(act[0])) { + ////////////////////////////////////////////// CANCEL CHANGE REQUEST NOTIFICATION + rAction = "cancelChangeRequest"; + + WearPlugin.getPlugin().requestNotificationCancel(rAction); + return; } else return; @@ -626,6 +645,11 @@ public class ActionStringHandler { doECarbs(carbs, starttime, duration); } else if ("dismissoverviewnotification".equals(act[0])) { MainApp.bus().post(new EventDismissNotification(SafeParse.stringToInt(act[1]))); + } else if ("changeRequest".equals(act[0])) { + LoopPlugin.getPlugin().acceptChangeRequest(); + NotificationManager notificationManager = + (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(Constants.notificationID); } lastBolusWizard = null; } 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 6cb47e1a3a..72b2397213 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 @@ -100,6 +100,12 @@ public class WearPlugin extends PluginBase { ctx.startService(new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS)); } + void requestNotificationCancel(String actionstring) { + Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION); + intent.putExtra("actionstring", actionstring); + ctx.startService(intent); + } + @Subscribe public void onStatusEvent(final EventPreferenceChange ev) { @@ -192,6 +198,15 @@ public class WearPlugin extends PluginBase { ctx.startService(intent); } + public void requestChangeConfirmation(String title, String message, String actionstring) { + + Intent intent = new Intent(ctx, WatchUpdaterService.class).setAction(WatchUpdaterService.ACTION_SEND_CHANGECONFIRMATIONREQUEST); + intent.putExtra("title", title); + intent.putExtra("message", message); + intent.putExtra("actionstring", actionstring); + ctx.startService(intent); + } + public static void registerWatchUpdaterService(WatchUpdaterService wus) { watchUS = wus; } 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 ce9b0e0f2f..4b4d1c4854 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 @@ -64,7 +64,8 @@ public class WatchUpdaterService extends WearableListenerService implements public static final String ACTION_SEND_BASALS = WatchUpdaterService.class.getName().concat(".SendBasals"); public static final String ACTION_SEND_BOLUSPROGRESS = WatchUpdaterService.class.getName().concat(".BolusProgress"); public static final String ACTION_SEND_ACTIONCONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(".ActionConfirmationRequest"); - + public static final String ACTION_SEND_CHANGECONFIRMATIONREQUEST = WatchUpdaterService.class.getName().concat(".ChangeConfirmationRequest"); + public static final String ACTION_CANCEL_NOTIFICATION = WatchUpdaterService.class.getName().concat(".CancelNotification"); private GoogleApiClient googleApiClient; public static final String WEARABLE_DATA_PATH = "/nightscout_watch_data"; @@ -79,6 +80,8 @@ public class WatchUpdaterService extends WearableListenerService implements public static final String BASAL_DATA_PATH = "/nightscout_watch_basal"; public static final String BOLUS_PROGRESS_PATH = "/nightscout_watch_bolusprogress"; public static final String ACTION_CONFIRMATION_REQUEST_PATH = "/nightscout_watch_actionconfirmationrequest"; + public static final String ACTION_CHANGECONFIRMATION_REQUEST_PATH = "/nightscout_watch_changeconfirmationrequest"; + public static final String ACTION_CANCELNOTIFICATION_REQUEST_PATH = "/nightscout_watch_cancelnotificationrequest"; boolean wear_integration = false; @@ -154,6 +157,14 @@ public class WatchUpdaterService extends WearableListenerService implements String message = intent.getStringExtra("message"); String actionstring = intent.getStringExtra("actionstring"); sendActionConfirmationRequest(title, message, actionstring); + } else if (ACTION_SEND_CHANGECONFIRMATIONREQUEST.equals(action)) { + String title = intent.getStringExtra("title"); + String message = intent.getStringExtra("message"); + String actionstring = intent.getStringExtra("actionstring"); + sendChangeConfirmationRequest(title, message, actionstring); + } else if (ACTION_CANCEL_NOTIFICATION.equals(action)) { + String actionstring = intent.getStringExtra("actionstring"); + sendCancelNotificationRequest(actionstring); } else { sendData(); } @@ -578,6 +589,42 @@ public class WatchUpdaterService extends WearableListenerService implements } } + private void sendChangeConfirmationRequest(String title, String message, String actionstring) { + if (googleApiClient.isConnected()) { + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CHANGECONFIRMATION_REQUEST_PATH); + //unique content + dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); + dataMapRequest.getDataMap().putString("changeConfirmationRequest", "changeConfirmationRequest"); + dataMapRequest.getDataMap().putString("title", title); + dataMapRequest.getDataMap().putString("message", message); + dataMapRequest.getDataMap().putString("actionstring", actionstring); + + log.debug("Requesting confirmation from wear: " + actionstring); + + PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); + } else { + Log.e("changeConfirmRequest", "No connection to wearable available!"); + } + } + + private void sendCancelNotificationRequest(String actionstring) { + if (googleApiClient.isConnected()) { + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(ACTION_CANCELNOTIFICATION_REQUEST_PATH); + //unique content + dataMapRequest.getDataMap().putLong("timestamp", System.currentTimeMillis()); + dataMapRequest.getDataMap().putString("cancelNotificationRequest", "cancelNotificationRequest"); + dataMapRequest.getDataMap().putString("actionstring", actionstring); + + log.debug("Canceling notification on wear: " + actionstring); + + PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest(); + Wearable.DataApi.putDataItem(googleApiClient, putDataRequest); + } else { + Log.e("cancelNotificationRequest", "No connection to wearable available!"); + } + } + private void sendStatus() { if (googleApiClient.isConnected()) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java index bc879bc2a7..f11d5c05b9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/XDripStatusline/StatuslinePlugin.java @@ -14,6 +14,8 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TemporaryBasal; +import info.nightscout.androidaps.events.EventAppInitialized; +import info.nightscout.androidaps.events.EventConfigBuilderChange; import info.nightscout.androidaps.events.EventExtendedBolusChange; import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.androidaps.events.EventPreferenceChange; @@ -80,7 +82,6 @@ public class StatuslinePlugin extends PluginBase { @Override protected void onStart() { MainApp.bus().register(this); - sendStatus(); super.onStart(); } @@ -182,6 +183,16 @@ public class StatuslinePlugin extends PluginBase { sendStatus(); } + @Subscribe + public void onStatusEvent(final EventAppInitialized ev) { + sendStatus(); + } + + @Subscribe + public void onStatusEvent(final EventConfigBuilderChange ev) { + sendStatus(); + } + @Subscribe public void onStatusEvent(final EventRefreshOverview ev) { //Filter events where loop is (de)activated diff --git a/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java b/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java index 43fbae83eb..e95cd7c479 100644 --- a/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java +++ b/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java @@ -18,7 +18,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.logging.L; public class AlarmSoundService extends Service { - private static Logger log = LoggerFactory.getLogger(L.ALARM); + private static Logger log = LoggerFactory.getLogger(L.CORE); MediaPlayer player; int resourceId = R.raw.error; @@ -35,14 +35,14 @@ public class AlarmSoundService extends Service { @Override public void onCreate() { super.onCreate(); - if (L.isEnabled(L.ALARM)) + if (L.isEnabled(L.CORE)) log.debug("onCreate"); } public int onStartCommand(Intent intent, int flags, int startId) { if (player != null && player.isPlaying()) player.stop(); - if (L.isEnabled(L.ALARM)) + if (L.isEnabled(L.CORE)) log.debug("onStartCommand"); if (intent != null && intent.hasExtra("soundid")) resourceId = intent.getIntExtra("soundid", R.raw.error); @@ -77,7 +77,7 @@ public class AlarmSoundService extends Service { public void onDestroy() { player.stop(); player.release(); - if (L.isEnabled(L.ALARM)) + if (L.isEnabled(L.CORE)) log.debug("onDestroy"); } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9bfe86c013..407b5467ed 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1,7 +1,7 @@ - Sicherheitseinstellungen Behandlungen + Sicherheitseinstellungen der Behandlungen Max. erlaubter Bolus [IE] Max. erlaubte Kohlenhydrate [g] Einstellungen @@ -26,7 +26,7 @@ Stand des Algorithmus in 2016 Stand des Algorithmus in 2017 Der aktuellste Algorithmus für erfahrene Nutzer - Zeigt den aktuellen Status deines Loops und Knöpfe für die gelaufigsten Aktionen an + Zeigt den aktuellen Status deines Loops und Knöpfe für die geläufigsten Aktionen an Zeigt eine fortlaufende Benachrichtigung mit einer kurzen Übersicht darüber, was dein Loop derzeit tut Definiere ein Profil, das auch offline verfügbar ist. Stellt das Profil zur Verfügung, das in Nightscout definiert ist @@ -802,6 +802,7 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Unbekannt Warte auf Code-Bestätigung Code abgelehnt + Verbinden zur App Nicht autorisiert Inkompatibel Sekunde @@ -822,7 +823,9 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Aktiviere SMB für sechs Stunden nach der Einnahme von Kohlenhydraten, auch mit 0 COB. Dies ist nur möglich, wenn eine BZ-Quelle genutzt wird, die die Daten besonders gut filtert wie z. B. G5. Aktiviere SMB während aktiver Kohlenhydrate. SMB aktivieren, wenn Kohlenhydrate aktiv sind. + Aktiviere SMB bei aktiven temporären Zielen Aktiviere SMB, wenn ein temporäres Ziel aktiv ist (bald essen, Aktivität) + Aktiviere SMB bei temporären Zielen oberhalb des regulären Ziels Aktiviere SMB bei temporären Zielen oberhalb des regulären Ziels (Aktivität). Temporäre Basalrate aktiv lassen Alarm stoppen @@ -842,11 +845,13 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Erstelle Nightscout-Ankündigungen für Fehler-Dialoge und lokale Alarme (auch einsehbar im Careportal unter \"Behandlungen\"). Zeige Vorhersagen auf dem Watchface. Vorhersagen + Datenübermittlung Fabric-Upload Erlauben, dass automatische Fehler-Berichte und Nutzungsstatistiken an die Entwickler über den Service von Fabric.io gesendet werden Bitte aktualisiere deine G5-App auf eine unterstützte Version. Starte TZ Aktivität Starte TZ Essen + TT Bolus nur erfassen Kategorie Unterkategorie @@ -943,7 +948,8 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Max. Autosens-Faktor Min. Autosens-Faktor Bolus-Snooze-DIA-Divisor - Max. tagesübergreifender Sicherheitsmultiplikator + Sicherheitsmultiplikator des Basalhöchstwertes + Sicherheitsmultiplikator der aktuellen Basalrate N/A BZ automatisch auffüllen Einrichtungsassistent @@ -952,23 +958,29 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Allgemeine Einstellungen Aktiviere Nightscout-Client Willkommen im Setup-Assistenten. Er führt Dich durch den Setup-Prozess\n + Pumpen-Einrichtung Status lesen Änderungen müssen in Nightscout vorgenommen werden. Einrichtungsassistenten überspringen Drücke die Schaltfläche unten, um AndroidAPS zu erlauben, Basal-Änderungen vorzuschlagen/vorzunehmen Drücken Sie die Taste unten, um die Zielsetzungen zu aktivieren. Nachdem Sie den Assistenten beendet haben, navigieren Sie zur Registerkarte Zielsetzungen, um alle AndroidAPS-Funktionen anzuzeigen.\n Zielsetzungen aktivieren + APS Plugin konfigurieren + Sensitivitäts Plugin konfigurieren Das Sensitivitäts-Plugin wird für die Sensitivitäts- und COB-Berechnung verwendet. Für weitere Informationen siehe: http://androidaps.readthedocs.io/en/latest/DE/konfigurations-generator.html#empfindlichkeitserkennung Nightscout-Client ist für die Verbindung zu Nightscout zuständig. Du kannst diesen Teil jetzt überspringen, aber Du wirst nicht in der Lage sein, Zielsetzungen zu erfüllen, bis Du diesen eingerichtet hast. + Bitte beachte: Neue Insulin-Profile benötigen einen DIA von mind. 5 Stunden. Eine DIA von 5-6 Stunden im neuen Insulin-Profil entspricht einem DIA von 3 Stunden bei alten Insulin-Profilen. BZ-Quelle konfigurieren Wähle eine Profilquelle aus. Verwende für ein Kind das NS-Profil. Wenn Dir niemand auf Nightscout folgt, wirst Du wahrscheinlich das lokale Profil bevorzugen. Beachte, dass hier nur die Profilquelle festgelegt wird. Damit das Profil verwendet werden kann, muss es mit einem \"Profil-Wechsel\" aktiviert werden. + Wähle einen der verfügbaren Algorithmen aus. Sie sind vom Ältesten zum Neuesten sortiert. Neuere Algorithmen sind meist stärker und aggressiver. Wenn du ein Anfänger bist, solltest du nicht mit dem Neuesten sondern mit AMA starten. Vergiss nicht, die OpenAPS-Dokumentation zu lesen und die entsprechenden Einstellungen vor der Benutzung vorzunehmen. Starte deine erste Zielsetzung Berechtigung Nach Berechtigung fragen AndroidAPS benötigt die Standortfreigabe für den BT-Scan. AndroidAPS benötigt Zugriff auf den Speicher, um Log-Dateien speichern zu können. Anfordern + Insulin Plugin konfigurieren Verlassen Benutzerdefinierte Einstellungen Zeitmodus @@ -978,15 +990,19 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Töne Vibration Beides + LCD-Einschaltdauer [s] BZ-Einheit Abschalten (h) + Reservoir fast leer (IE) In Pumpe speichern Ein Aus Menü öffnen Menü schließen + Plugin-Einstellungen Abgeschlossen, gut gemacht! Noch nicht vollständig ausgefüllt + Verstrichene Zeit %1$d. Ziel Poctech Empfange Blutzucker-Werte von der Poctech-App. @@ -1005,6 +1021,8 @@ maxIOB = durchschnittlicher Essensbolus + 3 x maximale Basalrate Der Eintrag (Insulin: %1$.2f, Kohlenhydrate: %2$d, um: %3$s) konnte nicht als Behandlung gespeichert werden. Bitte überprüfe die aktuelle Liste und füge, falls notwendig, den Datensatz manuell hinzu. eCarbs: %1$d g (%2$d h), Verzug: %3$d m Keine Autosens-Daten verfügbar + Log-Einstellungen + Auf Standardwerte zurücksetzen %1$d Tag %1$d Tage diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 3609b658b9..df39675a57 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -135,7 +135,7 @@ APS Efter begränsningar Temp basal satt i pump - Senast startad + Senaste justering OK Avbryt INGEN APS VALD @@ -225,7 +225,7 @@ Hittade inte filen Exportera inställningar Importera inställningar - Max enheter per timme som temp basal kan sättas till + Max enheter per timme Detta värde kallas max basal inom OpenAPS Maximal basal IOB som OpenAPS kan ge [E] Detta värde kallas Max IOB i OpenAPS. Det är ställt till noll från start. Efter flera dagar till veckor, beroende på hur du känner, kan du välja att justera denna. @@ -263,9 +263,9 @@ För att ge bolus %1$.2f enheter, svara med kod %2$s För att skicka kalibrering %1$.2f, svara med kod %2$s Bolus misslyckades - Bolus %.2f enheter korrekt tillförd - Kommer att tillföra %.2f enheter - Bolus %.2f enheter tillförd + Bolus %.2f enheter korrekt levererad + Kommer att leverera %.2f enheter + Bolus %.2f enheter levererad Levererar %.2f enheter Tillåt fjärrstyrning via SMS Fjärrbolus är inte tillåtet @@ -660,7 +660,7 @@ Serienummer Procent Tidsförskjutning - Standardvärde för temp mål + Standardmålvärden Äta snart [min] Mål vid Äta snart Träning [min] @@ -823,9 +823,9 @@ Använd SMB i 6 timmar efter kolhydrater, även med 0 COB. Endast möjligt med en bra filtrerad BG-källa, t ex Dexcom G5. Använd SMB med kolhydrater (COB) Använd SMB medan du har kolhydrater aktiva (COB) - Använd SMB när temp målvärde är satt + Använd SMB vid temp målvärde Använd SMB när temp mål är satt, t ex Äta snart eller Träning - Använd SMB även när ett högt temp målvärde är satt + Använd SMB vid högt målvärde Använd SMB även när ett högt temp målvärde är satt (över 5,5 mmol) Låt temp basalen gå Tysta @@ -1007,9 +1007,9 @@ %1$d. Mål Poctech Ta emot BG-data från Poctechappen - Högt temp målvärde höjer känsligheten + Högt målvärde höjer känsligheten - Lågt temp målvärde sänker känsligheten + Lågt målvärde sänker känsligheten Felaktig pumpinstallation. Kontrollera dokumentationen och verifiera att Snabbmenyn heter QUICK INFO med hjälp av 360-mjukvaran. Anpassad @@ -1022,6 +1022,8 @@ En behandling (insulin: %1$.2f, kolhydrater: %2$d, tid: %3$s) kunde inte läggas till listan i Behandlingar. Vänligen kontrollera och lägg till en post manuellt vid behov. Genererade eCarbs för %1$dg kolhydrater över %2$dh med fördröjning på %3$dm Ingen data tillgänglig för autosens + Loggningsinställningar + Återställ standardinställningar %1$d dag %1$d dagar diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index c3875572c1..8f1cb088dc 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -652,7 +652,7 @@ 血糖测量警报 剩余胰岛素数量 丹纳RS - 丹纳 + 丹纳泵 已选择的泵 配对新的泵 大剂量输注速度 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f1ac6b4784..b96ea3b55f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1178,11 +1178,12 @@ Delete Logs A treatment (insulin: %1$.2f, carbs: %2$d, at: %3$s) could not be added to treatments. Please check and manually add a record as appropriate. - Generated eCarbs with amount: %1$dg, duration: %2$dh, delay: %3$dm + eCarbs: %1$d g (%2$d h), delay: %3$d m key_plugin_stats_report_timestamp No autosens data available Log settings Reset to defaults + NSClient malfunction. Consider NS and NSClient restart. %1$d day diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java index 23352a57f9..2a742efc65 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.java @@ -4,17 +4,27 @@ import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.utils.SP; + /** * Created by mike on 19.03.2018. */ @RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class}) public class ConstraintTest { @Test - public void doTests() throws Exception { + public void doTests() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + Constraint b = new Constraint<>(true); Assert.assertEquals(Boolean.TRUE, b.value()); Assert.assertEquals("", b.getReasons()); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPluginTest.java index 59628a8dea..268faa5ab7 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPluginTest.java @@ -12,11 +12,12 @@ import org.powermock.modules.junit4.PowerMockRunner; import info.AAPSMocker; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.utils.SP; import static org.powermock.api.mockito.PowerMockito.mock; @RunWith(PowerMockRunner.class) -@PrepareForTest({MainApp.class}) +@PrepareForTest({MainApp.class, SP.class}) public class ConfigBuilderPluginTest { @Test @@ -41,9 +42,10 @@ public class ConfigBuilderPluginTest { } @Before - public void prepareMock() throws Exception { - MainApp mainApp = mock(MainApp.class); - PowerMockito.mockStatic(MainApp.class); + public void prepareMock() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); AAPSMocker.prepareMockedBus(); } diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_BasalTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_BasalTest.java index bbacbb485c..6831f889d7 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_BasalTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_Basal_Set_Temporary_BasalTest.java @@ -1,7 +1,18 @@ package info.nightscout.androidaps.plugins.PumpDanaRS.comm; +import android.content.Context; + import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.utils.SP; +import info.nightscout.utils.ToastUtils; import static org.junit.Assert.assertEquals; @@ -9,10 +20,15 @@ import static org.junit.Assert.assertEquals; * Created by mike on 20.11.2017. */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class}) public class DanaRS_Packet_APS_Basal_Set_Temporary_BasalTest extends DanaRS_Packet_APS_Basal_Set_Temporary_Basal { @Test - public void runTest() throws Exception { + public void runTest() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); // under 100% should last 30 min setParams(0); assertEquals(0, temporaryBasalRatio); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/PumpdanaRv2/comm/MsgSetAPSTempBasalStart_v2Test.java b/app/src/test/java/info/nightscout/androidaps/plugins/PumpdanaRv2/comm/MsgSetAPSTempBasalStart_v2Test.java index e36c5a7c24..d587363d60 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/PumpdanaRv2/comm/MsgSetAPSTempBasalStart_v2Test.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/PumpdanaRv2/comm/MsgSetAPSTempBasalStart_v2Test.java @@ -2,9 +2,15 @@ package info.nightscout.androidaps.plugins.PumpdanaRv2.comm; import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.plugins.PumpDanaRS.comm.DanaRS_Packet_APS_Basal_Set_Temporary_Basal; import info.nightscout.androidaps.plugins.PumpDanaRv2.comm.MsgSetAPSTempBasalStart_v2; +import info.nightscout.utils.SP; import static org.junit.Assert.assertEquals; @@ -12,10 +18,16 @@ import static org.junit.Assert.assertEquals; * Created by mike on 20.11.2017. */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class}) public class MsgSetAPSTempBasalStart_v2Test extends MsgSetAPSTempBasalStart_v2 { @Test - public void runTest() throws Exception { + public void runTest() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + // under 100% should last 30 min setParams(0); assertEquals(0, intFromBuff(buffer, 0, 2)); diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPluginTest.java index ec6c6e818f..e6d6caaf56 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/Sensitivity/AbstractSensitivityPluginTest.java @@ -1,13 +1,21 @@ package info.nightscout.androidaps.plugins.Sensitivity; import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensResult; import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin; +import info.nightscout.utils.SP; import static org.junit.Assert.assertEquals; +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class}) public class AbstractSensitivityPluginTest { private class SensitivityTestClass extends AbstractSensitivityPlugin { @@ -28,6 +36,10 @@ public class AbstractSensitivityPluginTest { @Test public void fillResultTest() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + SensitivityTestClass sut = new SensitivityTestClass(); AutosensResult ar = sut.fillResult(1d, 1d, "1", diff --git a/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java b/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java index 7297d51815..52dfc97ad1 100644 --- a/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java +++ b/wear/src/main/java/info/nightscout/androidaps/data/ListenerService.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.data; +import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -49,14 +51,18 @@ public class ListenerService extends WearableListenerService implements GoogleAp public static final String BASAL_DATA_PATH = "/nightscout_watch_basal"; public static final String BOLUS_PROGRESS_PATH = "/nightscout_watch_bolusprogress"; public static final String ACTION_CONFIRMATION_REQUEST_PATH = "/nightscout_watch_actionconfirmationrequest"; + public static final String NEW_CHANGECONFIRMATIONREQUEST_PATH = "/nightscout_watch_changeconfirmationrequest"; + public static final String ACTION_CANCELNOTIFICATION_REQUEST_PATH = "/nightscout_watch_cancelnotificationrequest"; public static final int BOLUS_PROGRESS_NOTIF_ID = 001; public static final int CONFIRM_NOTIF_ID = 002; + public static final int CHANGE_NOTIF_ID = 556677; private static final String ACTION_RESEND = "com.dexdrip.stephenblack.nightwatch.RESEND_DATA"; private static final String ACTION_CANCELBOLUS = "com.dexdrip.stephenblack.nightwatch.CANCELBOLUS"; private static final String ACTION_CONFIRMATION = "com.dexdrip.stephenblack.nightwatch.CONFIRMACTION"; + private static final String ACTION_CONFIRMCHANGE = "com.dexdrip.stephenblack.nightwatch.CONFIRMCHANGE"; private static final String ACTION_INITIATE_ACTION = "com.dexdrip.stephenblack.nightwatch.INITIATE_ACTION"; @@ -223,6 +229,17 @@ public class ListenerService extends WearableListenerService implements GoogleAp String actionstring = intent.getStringExtra("actionstring"); sendConfirmActionstring(actionstring); + } else if(intent != null && ACTION_CONFIRMCHANGE.equals(intent.getAction())){ + googleApiConnect(); + + //dismiss notification + NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(ListenerService.this); + notificationManager.cancel(CHANGE_NOTIF_ID); + + String actionstring = intent.getStringExtra("actionstring"); + sendConfirmActionstring(actionstring); + } else if(intent != null && ACTION_INITIATE_ACTION.equals(intent.getAction())){ googleApiConnect(); @@ -273,7 +290,7 @@ public class ListenerService extends WearableListenerService implements GoogleAp showConfirmationDialog(title, message, actionstring); } - }else if (path.equals(NEW_STATUS_PATH)) { + } else if (path.equals(NEW_STATUS_PATH)) { dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Intent messageIntent = new Intent(); messageIntent.setAction(Intent.ACTION_SEND); @@ -294,6 +311,14 @@ public class ListenerService extends WearableListenerService implements GoogleAp editor.putBoolean("wearcontrol", wearcontrol); editor.commit(); } + } else if (path.equals(NEW_CHANGECONFIRMATIONREQUEST_PATH)) { + String title = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("title"); + String message = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("message"); + String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("actionstring"); + notifyChangeRequest(title, message, actionstring); + } else if (path.equals(ACTION_CANCELNOTIFICATION_REQUEST_PATH)) { + String actionstring = DataMapItem.fromDataItem(event.getDataItem()).getDataMap().getString("actionstring"); + cancelNotificationRequest(actionstring); } else { dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap(); Intent messageIntent = new Intent(); @@ -305,6 +330,41 @@ public class ListenerService extends WearableListenerService implements GoogleAp } } + private void notifyChangeRequest(String title, String message, String actionstring) { + + Notification.Builder builder = + new Notification.Builder(this); //,"AndroidAPS-Openloop"); + builder.setSmallIcon(R.drawable.notif_icon) + .setContentTitle(title) + .setContentText(message) + .setPriority(Notification.PRIORITY_HIGH); + + // Creates an explicit intent for an Activity in your app + Intent intent = new Intent(this, AcceptActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Bundle params = new Bundle(); + params.putString("title", title); + params.putString("message", message); + params.putString("actionstring", actionstring); + intent.putExtras(params); + + PendingIntent resultPendingIntent = + PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + builder.setContentIntent(resultPendingIntent); + builder.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000}); + + NotificationManager mNotificationManager = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + // mId allows you to update the notification later on. + mNotificationManager.notify(CHANGE_NOTIF_ID, builder.build()); + } + + private void cancelNotificationRequest(String actionstring) { + NotificationManager mNotificationManager = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + mNotificationManager.cancel(CHANGE_NOTIF_ID); + } + private void showBolusProgress(int progresspercent, String progresstatus) { Intent cancelIntent = new Intent(this, ListenerService.class); cancelIntent.setAction(ACTION_CANCELBOLUS); @@ -409,7 +469,12 @@ public class ListenerService extends WearableListenerService implements GoogleAp public static void confirmAction(Context context, String actionstring) { Intent intent = new Intent(context, ListenerService.class); intent.putExtra("actionstring", actionstring); - intent.setAction(ACTION_CONFIRMATION); + + if (actionstring.equals("changeRequest")) { + intent.setAction(ACTION_CONFIRMCHANGE); + } else { + intent.setAction(ACTION_CONFIRMATION); + } context.startService(intent); } diff --git a/wear/src/main/res/drawable/notif_icon.png b/wear/src/main/res/drawable/notif_icon.png new file mode 100644 index 0000000000..480d0eaf77 Binary files /dev/null and b/wear/src/main/res/drawable/notif_icon.png differ