AndroidAPS/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt

125 lines
6.9 KiB
Kotlin
Raw Normal View History

2020-04-24 12:00:31 +02:00
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.Constants
2020-04-24 12:00:31 +02:00
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
2021-04-14 00:45:30 +02:00
import info.nightscout.androidaps.interfaces.ActivePlugin
2021-04-12 19:49:12 +02:00
import info.nightscout.androidaps.interfaces.IobCobCalculator
2020-12-25 12:06:54 +01:00
import info.nightscout.androidaps.interfaces.ProfileFunction
2020-04-24 12:00:31 +02:00
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
2020-12-25 12:06:54 +01:00
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
2020-04-24 12:00:31 +02:00
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
2020-04-24 12:00:31 +02:00
import javax.inject.Inject
import javax.inject.Singleton
2020-12-25 12:06:54 +01:00
import kotlin.math.min
2020-04-24 12:00:31 +02:00
/**
* Created by adrian on 17/12/17.
*/
@Singleton
class LocalAlertUtils @Inject constructor(
private val aapsLogger: AAPSLogger,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper,
2021-04-14 00:45:30 +02:00
private val activePlugin: ActivePlugin,
2020-04-24 12:00:31 +02:00
private val profileFunction: ProfileFunction,
2021-04-12 19:49:12 +02:00
private val iobCobCalculator: IobCobCalculator,
2020-12-25 12:06:54 +01:00
private val smsCommunicatorPlugin: SmsCommunicatorPlugin,
2020-05-07 23:40:59 +02:00
private val config: Config,
private val repository: AppRepository,
2020-05-07 23:40:59 +02:00
private val dateUtil: DateUtil
2020-04-24 12:00:31 +02:00
) {
private val disposable = CompositeDisposable()
2020-12-25 12:06:54 +01:00
private fun missedReadingsThreshold(): Long {
return T.mins(sp.getInt(R.string.key_missed_bg_readings_threshold_minutes, Constants.DEFAULT_MISSED_BG_READINGS_THRESHOLD_MINUTES).toLong()).msecs()
2020-04-24 12:00:31 +02:00
}
2020-12-25 12:06:54 +01:00
private fun pumpUnreachableThreshold(): Long {
return T.mins(sp.getInt(R.string.key_pump_unreachable_threshold_minutes, Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs()
2020-04-24 12:00:31 +02:00
}
fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) {
val alarmTimeoutExpired = isAlarmTimeoutExpired(lastConnection, pumpUnreachableThreshold())
2020-04-24 12:00:31 +02:00
val nextAlarmOccurrenceReached = sp.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis()
2020-12-25 12:06:54 +01:00
if (config.APS && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !isDisconnected) {
if (sp.getBoolean(R.string.key_enable_pump_unreachable_alert, true)) {
aapsLogger.debug(LTag.CORE, "Generating pump unreachable alarm. lastConnection: " + dateUtil.dateAndTimeString(lastConnection) + " isStatusOutdated: " + isStatusOutdated)
sp.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + pumpUnreachableThreshold())
2020-12-27 21:46:13 +01:00
rxBus.send(EventNewNotification(Notification(Notification.PUMP_UNREACHABLE, resourceHelper.gs(R.string.pump_unreachable), Notification.URGENT).also { it.soundId = R.raw.alarm }))
2020-12-25 12:06:54 +01:00
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true))
disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(resourceHelper.gs(R.string.pump_unreachable))).subscribe()
2020-04-24 12:00:31 +02:00
}
2020-12-25 12:06:54 +01:00
if (sp.getBoolean(R.string.key_smscommunicator_report_pump_ureachable, true))
smsCommunicatorPlugin.sendNotificationToAllNumbers(resourceHelper.gs(R.string.pump_unreachable))
2020-04-24 12:00:31 +02:00
}
if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE))
}
private fun isAlarmTimeoutExpired(lastConnection: Long, unreachableThreshold: Long): Boolean {
2020-12-25 12:06:54 +01:00
return if (activePlugin.activePump.pumpDescription.hasCustomUnreachableAlertCheck) {
activePlugin.activePump.isUnreachableAlertTimeoutExceeded(unreachableThreshold)
} else {
2020-12-25 12:06:54 +01:00
lastConnection + pumpUnreachableThreshold() < System.currentTimeMillis()
}
}
2020-12-25 12:06:54 +01:00
/*Pre-snoozes the alarms with 5 minutes if no snooze exists.
2020-04-24 12:00:31 +02:00
* Call only at startup!
*/
2020-12-25 12:06:54 +01:00
fun preSnoozeAlarms() {
2020-04-24 12:00:31 +02:00
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)
}
}
fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data
var nextMissedReadingsAlarm = sp.getLong("nextMissedReadingsAlarm", 0L)
2020-12-25 12:06:54 +01:00
nextMissedReadingsAlarm = min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm)
2020-04-24 12:00:31 +02:00
sp.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm)
var nextPumpDisconnectedAlarm = sp.getLong("nextPumpDisconnectedAlarm", 0L)
2020-12-25 12:06:54 +01:00
nextPumpDisconnectedAlarm = min(System.currentTimeMillis() + pumpUnreachableThreshold(), nextPumpDisconnectedAlarm)
2020-04-24 12:00:31 +02:00
sp.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm)
}
fun notifyPumpStatusRead() { //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm
val pump = activePlugin.activePump
val profile = profileFunction.getProfile()
if (profile != null) {
val lastConnection = pump.lastDataTime()
val earliestAlarmTime = lastConnection + pumpUnreachableThreshold()
if (sp.getLong("nextPumpDisconnectedAlarm", 0L) < earliestAlarmTime) {
sp.putLong("nextPumpDisconnectedAlarm", earliestAlarmTime)
}
}
}
fun checkStaleBGAlert() {
2021-04-13 18:33:44 +02:00
val bgReading = iobCobCalculator.ads.lastBg()
2020-12-25 12:06:54 +01:00
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
2021-02-06 00:30:27 +01:00
&& bgReading != null && bgReading.timestamp + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
2020-04-24 12:00:31 +02:00
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
n.soundId = R.raw.alarm
sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold())
rxBus.send(EventNewNotification(n))
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) {
n.text?.let { disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(it)).subscribe() }
2020-04-24 12:00:31 +02:00
}
}
}
}