diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 89c91fbc7d..ffbfb4b01c 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -1,7 +1,6 @@ package info.nightscout.androidaps; import android.app.Application; -import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.os.SystemClock; @@ -25,7 +24,6 @@ import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.Actions.ActionsFragment; import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; @@ -52,13 +50,9 @@ import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.ProfileSimple.SimpleProfilePlugin; import info.nightscout.androidaps.plugins.PumpCombo.ComboPlugin; import info.nightscout.androidaps.plugins.PumpDanaR.DanaRPlugin; -import info.nightscout.androidaps.plugins.PumpDanaR.services.DanaRExecutionService; import info.nightscout.androidaps.plugins.PumpDanaRKorean.DanaRKoreanPlugin; -import info.nightscout.androidaps.plugins.PumpDanaRKorean.services.DanaRKoreanExecutionService; import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin; -import info.nightscout.androidaps.plugins.PumpDanaRS.services.DanaRSService; import info.nightscout.androidaps.plugins.PumpDanaRv2.DanaRv2Plugin; -import info.nightscout.androidaps.plugins.PumpDanaRv2.services.DanaRv2ExecutionService; import info.nightscout.androidaps.plugins.PumpMDI.MDIPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin; @@ -221,7 +215,7 @@ public class MainApp extends Application { public void stopKeepAliveService() { if (keepAliveReceiver != null) - keepAliveReceiver.cancelAlarm(this); + KeepAliveReceiver.cancelAlarm(this); } public static Bus bus() { diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java index d573cc44be..46c524fa29 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandReadStatus.java @@ -1,8 +1,8 @@ package info.nightscout.androidaps.queue.commands; -import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.utils.LocalAlertUtils; /** * Created by mike on 09.11.2017. @@ -20,6 +20,7 @@ public class CommandReadStatus extends Command { @Override public void execute() { ConfigBuilderPlugin.getActivePump().getPumpStatus(); + LocalAlertUtils.notifyPumpStatusRead(); if (callback != null) callback.result(null).run(); } diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java index 83fa84e069..6ce75e3720 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveReceiver.java @@ -16,61 +16,38 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.db.BgReading; -import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.Overview.notifications.Notification; -import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; -import info.nightscout.utils.SP; +import info.nightscout.utils.LocalAlertUtils; public class KeepAliveReceiver extends BroadcastReceiver { private static Logger log = LoggerFactory.getLogger(KeepAliveReceiver.class); public static final long STATUS_UPDATE_FREQUENCY = 15 * 60 * 1000L; - // TODO consider moving this into an Alarms plugin that works offline and can be configured - // (e.g. override silent mode at night only) - - private static int missedReadingsThreshold() { - return SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30) * 60 * 1000; + public static void cancelAlarm(Context context) { + Intent intent = new Intent(context, KeepAliveReceiver.class); + PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0); + AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + alarmManager.cancel(sender); } - private static int pumpUnreachableThreshold() { - return SP.getInt(MainApp.sResources.getString(R.string.key_pump_unreachable_threshold), 30) * 60 * 1000; - } - - @Override public void onReceive(Context context, Intent rIntent) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ""); wl.acquire(); - shortenSnoozeInterval(); - checkBg(); + LocalAlertUtils.shortenSnoozeInterval(); + LocalAlertUtils.checkStaleBGAlert(); checkPump(); log.debug("KeepAlive received"); wl.release(); } - private void checkBg() { - BgReading bgReading = DatabaseHelper.lastBg(); - if (SP.getBoolean(MainApp.sResources.getString(R.string.key_enable_missed_bg_readings_alert), false) - && bgReading != null && bgReading.date + missedReadingsThreshold() < System.currentTimeMillis() - && SP.getLong("nextMissedReadingsAlarm", 0l) < System.currentTimeMillis()) { - Notification n = new Notification(Notification.BG_READINGS_MISSED, MainApp.sResources.getString(R.string.missed_bg_readings), Notification.URGENT); - n.soundId = R.raw.alarm; - SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold()); - MainApp.bus().post(new EventNewNotification(n)); - } - } - private void checkPump() { final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final Profile profile = MainApp.getConfigBuilder().getProfile(); @@ -79,16 +56,7 @@ public class KeepAliveReceiver extends BroadcastReceiver { boolean isStatusOutdated = lastConnection.getTime() + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis(); boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep; - boolean alarmTimeoutExpired = lastConnection.getTime() + pumpUnreachableThreshold() < System.currentTimeMillis(); - boolean nextAlarmOccurrenceReached = SP.getLong("nextPumpDisconnectedAlarm", 0l) < System.currentTimeMillis(); - - if (Config.APS && SP.getBoolean(MainApp.sResources.getString(R.string.key_enable_pump_unreachable_alert), true) - && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !ConfigBuilderPlugin.getActiveLoop().isDisconnected()) { - Notification n = new Notification(Notification.PUMP_UNREACHABLE, MainApp.sResources.getString(R.string.pump_unreachable), Notification.URGENT); - n.soundId = R.raw.alarm; - SP.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + pumpUnreachableThreshold()); - MainApp.bus().post(new EventNewNotification(n)); - } + LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated); if (!pump.isThisProfileSet(profile)) { MainApp.getConfigBuilder().getCommandQueue().setProfile(profile, null); @@ -103,8 +71,8 @@ public class KeepAliveReceiver extends BroadcastReceiver { //called by MainApp at first app start public void setAlarm(Context context) { - shortenSnoozeInterval(); - presnoozeAlarms(); + LocalAlertUtils.shortenSnoozeInterval(); + LocalAlertUtils.presnoozeAlarms(); AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent i = new Intent(context, KeepAliveReceiver.class); @@ -117,33 +85,4 @@ public class KeepAliveReceiver extends BroadcastReceiver { am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constants.keepAliveMsecs, pi); } - /*Presnoozes the alarms with 5 minutes if no snooze exists. - * Call only at startup! - */ - public void presnoozeAlarms() { - if (SP.getLong("nextMissedReadingsAlarm", 0l) < System.currentTimeMillis()) { - SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000); - } - if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < System.currentTimeMillis()) { - SP.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + 5 * 60 * 1000); - } - } - - public void cancelAlarm(Context context) { - Intent intent = new Intent(context, KeepAliveReceiver.class); - PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0); - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - alarmManager.cancel(sender); - } - - static void shortenSnoozeInterval() { - //shortens alarm times in case of setting changes or future data - long nextMissedReadingsAlarm = SP.getLong("nextMissedReadingsAlarm", 0L); - nextMissedReadingsAlarm = Math.min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm); - SP.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm); - - long nextPumpDisconnectedAlarm = SP.getLong("nextPumpDisconnectedAlarm", 0L); - nextPumpDisconnectedAlarm = Math.min(System.currentTimeMillis() + pumpUnreachableThreshold(), nextPumpDisconnectedAlarm); - SP.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm); - } } diff --git a/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java new file mode 100644 index 0000000000..e74818d447 --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/LocalAlertUtils.java @@ -0,0 +1,96 @@ +package info.nightscout.utils; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; + +import java.util.Date; + +import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.db.DatabaseHelper; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.Overview.notifications.Notification; +import info.nightscout.androidaps.receivers.KeepAliveReceiver; + +/** + * Created by adrian on 17/12/17. + */ + +public class LocalAlertUtils { + public static int missedReadingsThreshold() { + return SP.getInt(MainApp.sResources.getString(R.string.key_missed_bg_readings_threshold), 30) * 60 * 1000; + } + + private static int pumpUnreachableThreshold() { + return SP.getInt(MainApp.sResources.getString(R.string.key_pump_unreachable_threshold), 30) * 60 * 1000; + } + + public static void checkPumpUnreachableAlarm(Date lastConnection, boolean isStatusOutdated) { + boolean alarmTimeoutExpired = lastConnection.getTime() + pumpUnreachableThreshold() < System.currentTimeMillis(); + boolean nextAlarmOccurrenceReached = SP.getLong("nextPumpDisconnectedAlarm", 0l) < System.currentTimeMillis(); + + if (Config.APS && SP.getBoolean(MainApp.sResources.getString(R.string.key_enable_pump_unreachable_alert), true) + && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !ConfigBuilderPlugin.getActiveLoop().isDisconnected()) { + Notification n = new Notification(Notification.PUMP_UNREACHABLE, MainApp.sResources.getString(R.string.pump_unreachable), Notification.URGENT); + n.soundId = R.raw.alarm; + SP.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + pumpUnreachableThreshold()); + MainApp.bus().post(new EventNewNotification(n)); + } + } + + /*Presnoozes the alarms with 5 minutes if no snooze exists. + * Call only at startup! + */ + public static void presnoozeAlarms() { + if (SP.getLong("nextMissedReadingsAlarm", 0l) < System.currentTimeMillis()) { + SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000); + } + if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < System.currentTimeMillis()) { + SP.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + 5 * 60 * 1000); + } + } + + public static void shortenSnoozeInterval() { + //shortens alarm times in case of setting changes or future data + long nextMissedReadingsAlarm = SP.getLong("nextMissedReadingsAlarm", 0L); + nextMissedReadingsAlarm = Math.min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm); + SP.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm); + + long nextPumpDisconnectedAlarm = SP.getLong("nextPumpDisconnectedAlarm", 0L); + nextPumpDisconnectedAlarm = Math.min(System.currentTimeMillis() + pumpUnreachableThreshold(), nextPumpDisconnectedAlarm); + SP.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm); + } + + public static void notifyPumpStatusRead(){ + //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm + + final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); + final Profile profile = MainApp.getConfigBuilder().getProfile(); + if (pump != null && profile != null && profile.getBasal() != null) { + Date lastConnection = pump.lastDataTime(); + long earliestAlarmTime = lastConnection.getTime() + pumpUnreachableThreshold(); + if (SP.getLong("nextPumpDisconnectedAlarm", 0l) < earliestAlarmTime) { + SP.putLong("nextPumpDisconnectedAlarm", earliestAlarmTime); + } + } + } + + public static void checkStaleBGAlert() { + BgReading bgReading = DatabaseHelper.lastBg(); + if (SP.getBoolean(MainApp.sResources.getString(R.string.key_enable_missed_bg_readings_alert), false) + && bgReading != null && bgReading.date + missedReadingsThreshold() < System.currentTimeMillis() + && SP.getLong("nextMissedReadingsAlarm", 0l) < System.currentTimeMillis()) { + Notification n = new Notification(Notification.BG_READINGS_MISSED, MainApp.sResources.getString(R.string.missed_bg_readings), Notification.URGENT); + n.soundId = R.raw.alarm; + SP.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold()); + MainApp.bus().post(new EventNewNotification(n)); + } + } +}