SMS: report pump unreachable

This commit is contained in:
Milos Kozak 2020-12-25 12:06:54 +01:00
parent 4bf1f13ebc
commit 03c59d6e19
9 changed files with 44 additions and 32 deletions

View file

@ -146,7 +146,7 @@ class WizardDialog : DaggerDialogFragment() {
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged) treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
treatments_wizard_sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged) treatments_wizard_sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
val showCalc = sp.getBoolean(resourceHelper.gs(R.string.key_wizard_calculation_visible), false) val showCalc = sp.getBoolean(R.string.key_wizard_calculation_visible, false)
treatments_wizard_delimiter.visibility = showCalc.toVisibility() treatments_wizard_delimiter.visibility = showCalc.toVisibility()
treatments_wizard_resulttable.visibility = showCalc.toVisibility() treatments_wizard_resulttable.visibility = showCalc.toVisibility()
treatments_wizard_calculationcheckbox.isChecked = showCalc treatments_wizard_calculationcheckbox.isChecked = showCalc
@ -211,8 +211,8 @@ class WizardDialog : DaggerDialogFragment() {
} }
private fun loadCheckedStates() { private fun loadCheckedStates() {
treatments_wizard_bgtrendcheckbox.isChecked = sp.getBoolean(resourceHelper.gs(R.string.key_wizard_include_trend_bg), false) treatments_wizard_bgtrendcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_trend_bg, false)
treatments_wizard_cobcheckbox.isChecked = sp.getBoolean(resourceHelper.gs(R.string.key_wizard_include_cob), false) treatments_wizard_cobcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
} }
private fun initDialog() { private fun initDialog() {

View file

@ -267,8 +267,8 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("low_temptarget_lowers_sensitivity", false); mProfile.put("low_temptarget_lowers_sensitivity", false);
mProfile.put("sensitivity_raises_target", sp.getBoolean(resourceHelper.gs(R.string.key_sensitivity_raises_target),SMBDefaults.sensitivity_raises_target)); mProfile.put("sensitivity_raises_target", sp.getBoolean(R.string.key_sensitivity_raises_target,SMBDefaults.sensitivity_raises_target));
mProfile.put("resistance_lowers_target", sp.getBoolean(resourceHelper.gs(R.string.key_resistance_lowers_target),SMBDefaults.resistance_lowers_target)); mProfile.put("resistance_lowers_target", sp.getBoolean(R.string.key_resistance_lowers_target,SMBDefaults.resistance_lowers_target));
mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments); mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments);
mProfile.put("exercise_mode", SMBDefaults.exercise_mode); mProfile.put("exercise_mode", SMBDefaults.exercise_mode);
mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target); mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target);
@ -284,7 +284,7 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("enableUAM", uamAllowed); mProfile.put("enableUAM", uamAllowed);
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable); mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
boolean smbEnabled = sp.getBoolean(resourceHelper.gs(R.string.key_use_smb), false); boolean smbEnabled = sp.getBoolean(R.string.key_use_smb, false);
mProfile.put("SMBInterval", sp.getInt(R.string.key_smbinterval, SMBDefaults.SMBInterval)); mProfile.put("SMBInterval", sp.getInt(R.string.key_smbinterval, SMBDefaults.SMBInterval));
mProfile.put("enableSMB_with_COB", smbEnabled && sp.getBoolean(R.string.key_enableSMB_with_COB, false)); mProfile.put("enableSMB_with_COB", smbEnabled && sp.getBoolean(R.string.key_enableSMB_with_COB, false));
mProfile.put("enableSMB_with_temptarget", smbEnabled && sp.getBoolean(R.string.key_enableSMB_with_temptarget, false)); mProfile.put("enableSMB_with_temptarget", smbEnabled && sp.getBoolean(R.string.key_enableSMB_with_temptarget, false));

View file

@ -123,7 +123,7 @@ class ImportExportPrefs @Inject constructor(
} }
private fun prefsEncryptionIsDisabled() = private fun prefsEncryptionIsDisabled() =
buildHelper.isEngineeringMode() && !sp.getBoolean(resourceHelper.gs(R.string.key_maintenance_encrypt_exported_prefs), true) buildHelper.isEngineeringMode() && !sp.getBoolean(R.string.key_maintenance_encrypt_exported_prefs, true)
private fun askForMasterPass(activity: FragmentActivity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) { private fun askForMasterPass(activity: FragmentActivity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) {
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { password -> passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { password ->

View file

@ -77,7 +77,7 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
aapsLogger.debug(LTag.CORE, "KeepAlive scheduled") aapsLogger.debug(LTag.CORE, "KeepAlive scheduled")
SystemClock.sleep(5000) // wait for app initialization SystemClock.sleep(5000) // wait for app initialization
localAlertUtils.shortenSnoozeInterval() localAlertUtils.shortenSnoozeInterval()
localAlertUtils.presnoozeAlarms() localAlertUtils.preSnoozeAlarms()
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, KeepAliveReceiver::class.java) val i = Intent(context, KeepAliveReceiver::class.java)
val pi = PendingIntent.getBroadcast(context, 0, i, 0) val pi = PendingIntent.getBroadcast(context, 0, i, 0)

View file

@ -5,19 +5,21 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.BgReading import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification 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.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import kotlin.math.min
/** /**
* Created by adrian on 17/12/17. * Created by adrian on 17/12/17.
@ -31,48 +33,49 @@ class LocalAlertUtils @Inject constructor(
private val activePlugin: ActivePluginProvider, private val activePlugin: ActivePluginProvider,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin, private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
private val smsCommunicatorPlugin: SmsCommunicatorPlugin,
private val config: Config, private val config: Config,
private val nsUpload: NSUpload, private val nsUpload: NSUpload,
private val dateUtil: DateUtil private val dateUtil: DateUtil
) { ) {
fun missedReadingsThreshold(): Long { private fun missedReadingsThreshold(): Long {
return T.mins(sp.getInt(resourceHelper.gs(R.string.key_missed_bg_readings_threshold_minutes), Constants.DEFAULT_MISSED_BG_READINGS_THRESHOLD_MINUTES).toLong()).msecs() return T.mins(sp.getInt(R.string.key_missed_bg_readings_threshold_minutes, Constants.DEFAULT_MISSED_BG_READINGS_THRESHOLD_MINUTES).toLong()).msecs()
} }
fun pumpUnreachableThreshold(): Long { private fun pumpUnreachableThreshold(): Long {
return T.mins(sp.getInt(resourceHelper.gs(R.string.key_pump_unreachable_threshold_minutes), Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs() return T.mins(sp.getInt(R.string.key_pump_unreachable_threshold_minutes, Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs()
} }
fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) { fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) {
val alarmTimeoutExpired = isAlarmTimeoutExpired(lastConnection, pumpUnreachableThreshold()) val alarmTimeoutExpired = isAlarmTimeoutExpired(lastConnection, pumpUnreachableThreshold())
val nextAlarmOccurrenceReached = sp.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis() val nextAlarmOccurrenceReached = sp.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis()
if (config.APS && sp.getBoolean(resourceHelper.gs(R.string.key_enable_pump_unreachable_alert), true) if (config.APS && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !isDisconnected) {
&& 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) aapsLogger.debug(LTag.CORE, "Generating pump unreachable alarm. lastConnection: " + dateUtil.dateAndTimeString(lastConnection) + " isStatusOutdated: " + isStatusOutdated)
val n = Notification(Notification.PUMP_UNREACHABLE, resourceHelper.gs(R.string.pump_unreachable), Notification.URGENT)
n.soundId = R.raw.alarm
sp.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + pumpUnreachableThreshold()) sp.putLong("nextPumpDisconnectedAlarm", System.currentTimeMillis() + pumpUnreachableThreshold())
rxBus.send(EventNewNotification(n)) rxBus.send(EventNewNotification(Notification(Notification.PUMP_UNREACHABLE, resourceHelper.gs(R.string.pump_unreachable), Notification.URGENT).also { it.soundId - R.raw.alarm }))
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) { if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true))
nsUpload.uploadError(n.text) nsUpload.uploadError(resourceHelper.gs(R.string.pump_unreachable))
} }
if (sp.getBoolean(R.string.key_smscommunicator_report_pump_ureachable, true))
smsCommunicatorPlugin.sendNotificationToAllNumbers(resourceHelper.gs(R.string.pump_unreachable))
} }
if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE)) if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE))
} }
private fun isAlarmTimeoutExpired(lastConnection: Long, unreachableThreshold: Long): Boolean { private fun isAlarmTimeoutExpired(lastConnection: Long, unreachableThreshold: Long): Boolean {
if (activePlugin.activePump.pumpDescription.hasCustomUnreachableAlertCheck) { return if (activePlugin.activePump.pumpDescription.hasCustomUnreachableAlertCheck) {
return activePlugin.activePump.isUnreachableAlertTimeoutExceeded(unreachableThreshold) activePlugin.activePump.isUnreachableAlertTimeoutExceeded(unreachableThreshold)
} else { } else {
return lastConnection + pumpUnreachableThreshold() < System.currentTimeMillis() lastConnection + pumpUnreachableThreshold() < System.currentTimeMillis()
} }
} }
/*Presnoozes the alarms with 5 minutes if no snooze exists. /*Pre-snoozes the alarms with 5 minutes if no snooze exists.
* Call only at startup! * Call only at startup!
*/ */
fun presnoozeAlarms() { fun preSnoozeAlarms() {
if (sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) { if (sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000) sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000)
} }
@ -83,10 +86,10 @@ class LocalAlertUtils @Inject constructor(
fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data
var nextMissedReadingsAlarm = sp.getLong("nextMissedReadingsAlarm", 0L) var nextMissedReadingsAlarm = sp.getLong("nextMissedReadingsAlarm", 0L)
nextMissedReadingsAlarm = Math.min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm) nextMissedReadingsAlarm = min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm)
sp.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm) sp.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm)
var nextPumpDisconnectedAlarm = sp.getLong("nextPumpDisconnectedAlarm", 0L) var nextPumpDisconnectedAlarm = sp.getLong("nextPumpDisconnectedAlarm", 0L)
nextPumpDisconnectedAlarm = Math.min(System.currentTimeMillis() + pumpUnreachableThreshold(), nextPumpDisconnectedAlarm) nextPumpDisconnectedAlarm = min(System.currentTimeMillis() + pumpUnreachableThreshold(), nextPumpDisconnectedAlarm)
sp.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm) sp.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm)
} }
@ -104,7 +107,7 @@ class LocalAlertUtils @Inject constructor(
fun checkStaleBGAlert() { fun checkStaleBGAlert() {
val bgReading: BgReading? = iobCobCalculatorPlugin.lastBg() val bgReading: BgReading? = iobCobCalculatorPlugin.lastBg()
if (sp.getBoolean(resourceHelper.gs(R.string.key_enable_missed_bg_readings_alert), false) if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
&& bgReading != null && bgReading.date + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) { && bgReading != null && bgReading.date + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT) val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
n.soundId = R.raw.alarm n.soundId = R.raw.alarm

View file

@ -1415,5 +1415,8 @@
<string name="copytolocalprofile_invalid">Unable to create local profile. Profile is invalid.</string> <string name="copytolocalprofile_invalid">Unable to create local profile. Profile is invalid.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string> <string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="alarm">Alarm</string> <string name="alarm">Alarm</string>
<string name="key_smscommunicator_report_pump_ureachable" translatable="false">smscommunicator_report_pump_ureachable</string>
<string name="smscommunicator_report_pump_ureachable_summary">Send SMS if unreachable pump event is triggered</string>
<string name="smscommunicator_pump_ureachable">Report pump ureachable</string>
</resources> </resources>

View file

@ -49,6 +49,12 @@
<intent android:action="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" /> <intent android:action="info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity" />
</Preference> </Preference>
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_smscommunicator_report_pump_ureachable"
android:summary="@string/smscommunicator_report_pump_ureachable_summary"
android:title="@string/smscommunicator_pump_ureachable" />
</PreferenceCategory> </PreferenceCategory>
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>

View file

@ -184,7 +184,7 @@ public abstract class AbstractDanaRExecutionService extends DaggerService {
} }
protected void getBTSocketForSelectedPump() { protected void getBTSocketForSelectedPump() {
mDevName = sp.getString(resourceHelper.gs(R.string.key_danar_bt_name), ""); mDevName = sp.getString(R.string.key_danar_bt_name, "");
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) { if (bluetoothAdapter != null) {

View file

@ -596,7 +596,7 @@ class OmnipodOverviewFragment : DaggerFragment() {
// FIXME ideally we should just have access to LocalAlertUtils here // FIXME ideally we should just have access to LocalAlertUtils here
private fun getPumpUnreachableTimeout(): Duration { private fun getPumpUnreachableTimeout(): Duration {
return Duration.standardMinutes(sp.getInt(resourceHelper.gs(R.string.key_pump_unreachable_threshold_minutes), Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()) return Duration.standardMinutes(sp.getInt(R.string.key_pump_unreachable_threshold_minutes, Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong())
} }
inner class DisplayResultDialogCallback(private val errorMessagePrefix: String, private val withSoundOnError: Boolean) : Callback() { inner class DisplayResultDialogCallback(private val errorMessagePrefix: String, private val withSoundOnError: Boolean) : Callback() {