2020-04-24 12:00:31 +02:00
|
|
|
package info.nightscout.androidaps.utils
|
|
|
|
|
2020-08-29 01:44:31 +02:00
|
|
|
import info.nightscout.androidaps.Constants
|
2020-04-24 12:00:31 +02:00
|
|
|
import info.nightscout.androidaps.R
|
2021-03-28 13:45:27 +02:00
|
|
|
import info.nightscout.androidaps.database.AppRepository
|
2021-10-30 13:43:22 +02:00
|
|
|
import info.nightscout.androidaps.database.ValueWrapper
|
2021-07-14 17:30:09 +02:00
|
|
|
import info.nightscout.androidaps.database.entities.TherapyEvent
|
|
|
|
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
|
|
|
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
|
|
|
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
2021-03-28 13:45:27 +02:00
|
|
|
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
|
2021-04-14 00:45:30 +02:00
|
|
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
2021-10-30 13:43:22 +02:00
|
|
|
import info.nightscout.androidaps.interfaces.Config
|
2020-12-25 12:06:54 +01:00
|
|
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
2021-12-10 15:19:19 +01:00
|
|
|
import info.nightscout.shared.logging.AAPSLogger
|
|
|
|
import info.nightscout.shared.logging.LTag
|
2021-07-14 17:30:09 +02:00
|
|
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
2021-10-15 14:56:22 +02:00
|
|
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
2020-04-24 12:00:31 +02:00
|
|
|
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
|
2021-12-10 12:17:03 +01:00
|
|
|
import info.nightscout.shared.sharedPreferences.SP
|
2021-03-28 13:45:27 +02:00
|
|
|
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,
|
2021-10-15 14:56:22 +02:00
|
|
|
private val rxBus: RxBus,
|
2021-11-04 10:56:12 +01:00
|
|
|
private val rh: 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,
|
2020-12-25 12:06:54 +01:00
|
|
|
private val smsCommunicatorPlugin: SmsCommunicatorPlugin,
|
2020-05-07 23:40:59 +02:00
|
|
|
private val config: Config,
|
2021-03-28 13:45:27 +02:00
|
|
|
private val repository: AppRepository,
|
2021-07-14 17:30:09 +02:00
|
|
|
private val dateUtil: DateUtil,
|
|
|
|
private val uel: UserEntryLogger
|
2020-04-24 12:00:31 +02:00
|
|
|
) {
|
|
|
|
|
2021-03-28 13:45:27 +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) {
|
2020-08-10 22:27:52 +02:00
|
|
|
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())
|
2021-11-04 10:56:12 +01:00
|
|
|
rxBus.send(EventNewNotification(Notification(Notification.PUMP_UNREACHABLE, rh.gs(R.string.pump_unreachable), Notification.URGENT).also { it.soundId = R.raw.alarm }))
|
|
|
|
uel.log(Action.CAREPORTAL, Sources.Aaps, rh.gs(R.string.pump_unreachable), ValueWithUnit.TherapyEventType(TherapyEvent.Type.ANNOUNCEMENT))
|
2020-12-25 12:06:54 +01:00
|
|
|
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true))
|
2021-11-04 10:56:12 +01:00
|
|
|
disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(rh.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))
|
2021-11-04 10:56:12 +01:00
|
|
|
smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable))
|
2020-04-24 12:00:31 +02:00
|
|
|
}
|
|
|
|
if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE))
|
|
|
|
}
|
|
|
|
|
2020-08-10 22:27:52 +02:00
|
|
|
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)
|
2020-08-10 22:27:52 +02:00
|
|
|
} else {
|
2020-12-25 12:06:54 +01:00
|
|
|
lastConnection + pumpUnreachableThreshold() < System.currentTimeMillis()
|
2020-08-10 22:27:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-10-30 13:43:22 +02:00
|
|
|
val bgReadingWrapped = repository.getLastGlucoseValueWrapped().blockingGet()
|
|
|
|
val bgReading = if (bgReadingWrapped is ValueWrapper.Existing) bgReadingWrapped.value else return
|
2020-12-25 12:06:54 +01:00
|
|
|
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
|
2021-10-30 13:43:22 +02:00
|
|
|
&& bgReading.timestamp + missedReadingsThreshold() < System.currentTimeMillis()
|
|
|
|
&& sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()
|
|
|
|
) {
|
2021-11-04 10:56:12 +01:00
|
|
|
val n = Notification(Notification.BG_READINGS_MISSED, rh.gs(R.string.missed_bg_readings), Notification.URGENT)
|
2020-04-24 12:00:31 +02:00
|
|
|
n.soundId = R.raw.alarm
|
|
|
|
sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold())
|
|
|
|
rxBus.send(EventNewNotification(n))
|
2021-11-04 10:56:12 +01:00
|
|
|
uel.log(Action.CAREPORTAL, Sources.Aaps, rh.gs(R.string.missed_bg_readings), ValueWithUnit.TherapyEventType(TherapyEvent.Type.ANNOUNCEMENT))
|
2020-04-24 12:00:31 +02:00
|
|
|
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) {
|
2021-03-28 13:45:27 +02:00
|
|
|
n.text?.let { disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(it)).subscribe() }
|
2020-04-24 12:00:31 +02:00
|
|
|
}
|
2021-10-30 13:43:22 +02:00
|
|
|
} else if (dateUtil.isOlderThan(bgReading.timestamp, 5).not()) {
|
|
|
|
rxBus.send(EventDismissNotification(Notification.BG_READINGS_MISSED))
|
2020-04-24 12:00:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|